<?php
class Game{
    # region 已完成的指定期数红包
    public static function getGameForIssueIsEnd($issue)
    {
        global $db;
        global $redis;
        global $utility;

        $redis_key = 'games_item_for_'.$issue;

        $data = $utility->redisGet($redis, $redis_key);
        if(!$data){
            $sql = "SELECT b.`id`,b.`uid`,b.`issue`,b.`gameid`,b.`cardtype`,b.`odds`,b.`mantissa`,b.`coin`,b.`times`,b.`ticket`,b.`winerprofit`,b.`profit`,u.`uid` AS userid,u.`nickname`,u.`avatar` ";
            $sql .="FROM `rp_betslog` b,`rp_users` u WHERE u.`uid`=b.`uid` AND b.`issue`='{$issue}' ORDER BY b.`times` ASC";
            $data['grabusers'] = $db->query($sql);
            $sql = "SELECT * FROM `rp_bets` WHERE `issue`='{$issue}'";
            $data['datas'] = $db->row($sql);
            $utility->redisSetEx($redis, $redis_key, $data);
        }
        return $data;
    }
    # endregion

    # region 指定期数的红包 -- 用于展示
    public static function getRedPacketForIssue($issue)
    {
        global $db;
        $sql = "SELECT `id`,`need`,`begintimes`,`coin`,`gameid`,`overtime` FROM `rp_bets` WHERE `issue`='{$issue}' LIMIT 1";
        $data = $db->row($sql);
        $nowtime = time();
        $result = array(
            'id'=> $data['id'],
            'issue'=> $issue,
            'need' => $data['need'],
            'coin' => $data['coin'],
            'game' => $data['gameid'],
            'begintimes' => $data['begintimes'],
            'overtime' => ($data['begintimes'] + intval($data['overtime'])) - $nowtime,
        );
        return $result;
    }
    # endregion

    # region 生成当前游戏类型的期号
    public static function getIssue($gameid){
        global $db;
        global $redis;
        global $utility;

        $redis_key = \Config\Sys::$redisKey['GISSUE'] . $gameid . '_count';
        $redis_key_date = \Config\Sys::$redisKey['GISSUE'] . $gameid . '_createdate';
        $issue_nums_len = 6;
        $issue_nums = 1000000; //要保留的期号长度,当前数字少一位数
        $nowdate = strval(date('Ymd'));
        # 如果Key存在且创建的日期是今天即从Redis缓存中取期数
        //if($redis->exists($redis_key) && $nowdate==$redis->get($redis_key_date))
        //{
        //    $redis_issue = $redis->get($redis_key);
        //    $_issue = substr($redis_issue,-1,$issue_nums_len);
        //    $sourceNumber = intval($_issue) + 1;
        //    $newNumber = substr(strval($sourceNumber + $issue_nums), 1, 6);
        //}else {
        $beginTimes = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
        $endTimes = $beginTimes + 86400;
        $sql = "SELECT (COUNT(1)+1) AS _TOTAL FROM `rp_bets` WHERE `begintimes`>={$beginTimes} AND `begintimes`<={$endTimes} AND `gameid`={$gameid}";
        $issue_db = $db->row($sql);
        $sourceNumber = $issue_db['_TOTAL'];
        $newNumber = substr(strval($sourceNumber + $issue_nums), 1, 6);
        //}
        $issue = date('Ymd') . $gameid . $newNumber;
        # 写入Redis
        $utility->redisSet($redis_key, $issue);
        $utility->redisSet($redis_key_date, $nowdate);
        return $issue;
    }
    # endregion

    # region 拉取游戏规则介绍
    public static function gameRule($paras)
    {
        global $db;
        global $redis;
        global $utility;

        $mastArgs = array(
            'gameid|N',
            'cmd',
        );
        $paras = $utility->get_url_args($paras, $mastArgs);

        $result = array('state'=>404, 'cmd'=>$paras['cmd']);
        if(empty($paras['gameid']))
        {
            $result['msgid'] = 301;
            return $result;
        }
        $redis_key = Config\Sys::$redisKey['GRFC'].$paras['gameid'];
        $result['rule'] = '暂无内容';

        $rule = $utility->redisGet($redis_key);

        if(!$rule){
            $rule = $db->row("SELECT `content` FROM `".\Config\Sys::$dbprefix."games_rule` WHERE `gameid`={$paras['gameid']} LIMIT 1");
            $rule = $utility->replaceKeys($rule['content']);
            $utility->redisGet($redis_key, $rule);
        }


        if($rule){
            $result['state'] = 200;
            $result['rule'] = $rule;
        }
        //print_r($result);
        return $result;
    }
    # endregion

    # region 当前红包期数的所有玩家
    public static function getGrabUserList($issue)
    {
        global $db;
        $sql = "SELECT b.`id`,b.`uid`,b.`issue`,b.`gameid`,b.`cardtype`,b.`odds`,b.`mantissa`,b.`coin`,b.`times`,b.`ticket`,b.`winerprofit`,b.`profit`,u.`uid` AS userid,u.`nickname`,u.`avatar` ";
        $sql .="FROM `rp_betslog` b,`rp_users` u WHERE u.`uid`=b.`uid` AND b.`issue`='{$issue}' ORDER BY b.`times` ASC";
        $grabusers = $db->query($sql);

        return $grabusers;
    }
    # endregion

    #region 取游戏首页的轮播
    public static function getGameBanners()
    {
        global $db;
        global $redis;
        global $utility;

        $redis_key = Config\Sys::$redisKey['GHBS'];
        $data = $utility->redisGet($redis_key);

        if(!$data){
            $nowtime = time();
            $fields = "`id`, `title`, REPLACE(`pic`,'/upload/','') as icon, `url` as href";
            $wheres = "`state`=1 AND `actiontime`<{$nowtime} AND (`endtime`>{$nowtime} or `endtime`=0) AND `categoryid`=1";
            $orderby = " ORDER BY `sort` ASC";

            $tablename = Config\Sys::$dbprefix.'advs';

            $sql = "SELECT {$fields} FROM {$tablename} WHERE {$wheres} {$orderby}";
            $data = $db->query($sql);

            $utility->redisSet($redis_key, $data);
        }
        return $data;
    }
    # endregion

    # region 取所有可用状态的游戏
    public static function getGameList()
    {
        global $db;
        global $redis;
        global $utility;

        $redis_key = Config\Sys::$redisKey['GLAS'];

        $data = $utility->redisGet($redis_key);

        if(!$data){
            //$fields = "id, title, func, icon, establishcost, ishavebanker, establishcoin, manymen, custombetscoin, betscoinlist, minbetcoin, maxbetcoin, overtime, state";
            $fields = "id, title, func, icon";
            $wheres = "`state`=1";
            $orderby = " ORDER BY `sort` ASC";
            $tablename = Config\Sys::$dbprefix.'games';

            $sql = "SELECT {$fields} FROM {$tablename} WHERE {$wheres} {$orderby}";
            $data = $db->query($sql);

            $utility->redisSet($redis_key, $data);
        }
        return $data;
    }
    # endregion

    # region 游戏首页数据整合返回
    public static function GameHomeData()
    {
        global $utility;
        $data['gameslist'] = self::getGameList();
        $data['banners'] = self::getGameBanners();
        $data['homeservice'] = $utility->getSystemParams('homeservice');
        $data['helpid'] = $utility->getSystemParams('helpid');
        return $data;
    }
    # endregion

    # region 取游戏的参数不包括赔率
    /**
     * 取游戏的参数不包括赔率
     * @param $gameid
     * @return mixed
     */
    public static function getGameForID($gameid)
    {
        global $db;
        global $redis;
        global $utility;
        $redis_key = 'games_item_forid_'.$gameid;
        $data = $utility->redisGet($redis_key);
        if(!$data){
            $where = "`id`={$gameid}";
            $fields = "id, title, func, establishcost, ishavebanker, establishcoin, manymen, custombetscoin, betscoinlist, minbetcoin, maxbetcoin, overtime, maxodds, state, passcoin";
            $tablename = \Config\Sys::$dbprefix."games";
            $sql = "SELECT {$fields} FROM `{$tablename}` WHERE {$where}";
            $data = $db->row($sql);
            $utility->redisSet($redis_key, $data);
        }
        return $data;
    }
    # endregion

    # region 取游戏的参数及对应的赔率设置
    /***
     * 取游戏的参数及对应的赔率设置
     * @param $db 数据库连接对象
     * @param $gameid int 游戏的ID
     * @param $needuser int 需要参与的人数
     * @return array 游戏的参数及游戏对应的赔率设置
     */
    public static function getGameAndOddsForGameID($gameid, $needuser = 5)
    {
        global $db;
        global $redis;
        global $utility;
        $redis_key = \Config\Sys::$redisKey['GPOP'].$gameid.'_'.$needuser;
        $data = $utility->redisGet($redis_key);

        if(!$data){
            $sql = "SELECT id, title, func, establishcost, ishavebanker, establishcoin, manymen, custombetscoin, betscoinlist, minbetcoin, maxbetcoin, overtime, maxodds, state, passcoin FROM ".\Config\Sys::$dbprefix."games WHERE id=" . $gameid . " LIMIT 1";
            $games = $db->row($sql);

            $sql = "SELECT * FROM `rp_games_odds` WHERE `gameid`=".$gameid." AND `manymen`=".$needuser." ORDER BY `winsort` DESC";
            $odds = $db->query($sql);

            $data = array(
                'game' => $games,
                'odds' => $odds,
            );

            $utility->redisSet($redis_key, $data);
        }
        return $data;
    }
    # endregion

    # region 还在抢的红包数据 - getGameAndOddsForGameID
    /**
     * 找出还在抢的红包数据（进行中的）
     * @param $db_id object 数据库对象
     * @param $game_id int 游戏类型
     */
    public static function getGrabingRedpacket($gameid)
    {
        global $db;
        $where = "(overtime - (UNIX_TIMESTAMP() - begintimes)) > 0 AND b.`uid`=u.`uid` AND b.`state`=0 AND b.`need`>b.`cur` AND b.`gameid`={$gameid}";
        $fields = "b.`id`,b.`issue`,b.`mantissa`,b.`nickname`,b.`need`,b.`cur`,b.`coin`,b.`begintimes`,b.`overtime`,u.`avatar`,";
        $fields .= "(case when b.`pass`='' then 0 else 1 end) AS ispass,b.`usertype`";
        $tablename = '`'.\Config\Sys::$dbprefix.'bets` b,`'.\Config\Sys::$dbprefix.'users` u';
        $sql = "SELECT {$fields} FROM {$tablename} WHERE {$where}";
        $result = $db->query($sql);
        return $result;
    }
    # endregion

    # region 拉取游戏参数 - joinToGameForIdData
    /**
     * 加入游戏时拉取相关的参数
     * @param $paras
     */
    public static function joinToGameForIdData($paras)
    {
        global $utility;

        $mastArgs = array('token','cmd','room_id|N','game_id','roomtype|N','red_issue');
        $paras = $utility->get_url_args($paras, $mastArgs);

        $user = $utility->exitsToKen($paras['token'],$paras['cmd']);

        $result['online'] = $utility->getUserOnline();
        $result['state'] = 404;
        $result['cmd'] = $paras['cmd'];
        $result['room_id'] = $paras['room_id'];
        $result['game_id'] = $paras['game_id'];

        if($user['state']==200){
            $gameid = $utility->getGameOrChatID($paras['game_id']);
            $result['state'] = 200;
            unset($result['msgid']);
            $result['user'] = $user;
            $result['game_room_en_name'] = \Config\Sys::$gameprefix.$paras['game_id'];
            # //如果期数提供,要返回给玩家通知加入到这个组，以便收到通知
            $result['red_issue'] = $paras['red_issue'];
            //取游戏参数
            $gameinfo = self::getGameForID($gameid);
            $result['gameinfo'] = $gameinfo;
            //找出没有完成的红包
            $result['grabing'] = self::getGrabingRedpacket($gameid);
            //$result['datas'] = $this->db->query("SELECT b.`id`,b.`issue`,b.`nickname`,b.`need`,b.`cur`,b.`coin`,b.`begintimes`,b.`overtime`,IF(u.`avatar`,u.`avatar`,'no') AS avatar FROM `rp_bets` b,`rp_users` u WHERE b.`uid`=u.`id` AND b.`state`=0 AND b.`need`>b.`cur` AND b.`gameid`={$game_id}");
        }else{
            $result['state'] = $user['state'];
            $result['msgid'] = $user['msgid'];
        }
        return $result;
    }
    # endregion

    # region 红包超时处理 - timeOutRedEnveloes
    /**
     * 红包超时处理
     * @param $paras
     * @return mixed
     */
    public static function timeOutRedEnveloes($paras)
    {
        global $db;
        global $redis;
        global $utility;

        $mastArgs = array(
            'token',
            'cmd',
            'red_issue',
            'state|N|0',
        );
        $paras = $utility->get_url_args($paras, $mastArgs);
        $paras['nowtime'] = time();

        $db_prefix = \Config\Sys::$dbprefix;
        $result['cmd'] = $paras['cmd'];

        if(empty($paras['red_issue']))
        {
            $result['state'] = 404;
            $result['msgid'] = 10020;
            return $result;
        }
        # 如果已经已经作了结算就不要再进行这个超时了
        # 2018-01-11 2:54
        $gameover_redis_key = \Config\Sys::$redisKey['GISSUE'].$paras['red_issue'].'_gameover';
        if($redis->exists($gameover_redis_key))
        {
            return array(
                'state' => 404,
                'msgid' => 404,
                'msg' => 'Is gameover',
            );
        }else{
            if($redis->exists($gameover_redis_key . '_timeout'))
            {
                //print_r('游戏超时：' . $gameover_redis_key . '_timeout -- 其它进程已处理超时' . "\n");
                return array(
                    'state' => 404,
                    'msgid' => 404,
                    'msg' => 'is timeout',
                );
            }else {
                $utility->redisSetEx($gameover_redis_key . '_timeout', 1, 120);
            }
        }

        //找出当前期数的红包
        $red_data = $db->row("SELECT * FROM `{$db_prefix}bets` WHERE `issue`='{$paras['red_issue']}' AND `state`=0");

        //是否超时
        $overtime = (intval($red_data['begintimes']) + intval($red_data['overtime']) - $paras['nowtime']);
        //没有超时时提示
        if($overtime > 0)
        {
            $result['state'] = 404;
            $result['msgid'] = 301; //没有超时时提示指令对数不对
            return $result;
        }
        //$user = $utility->exitsToKen($paras['token'],$paras['cmd']);

        //if($user['state']==200){
        $game_id = $red_data['gameid'];
        $room_id = \Config\Sys::$gameprefix.$game_id;

        //找出对应游戏的参数，并执行相应过程
        $gameinfo = self::getGameAndOddsForGameID($game_id, $red_data['need']);
        //取出当前期数红包参与的所有玩家
        $grabusers = self::getGrabUserList($red_data['issue']);
        return self::grabRedEnvelopesOver($room_id, $gameinfo, $red_data, $grabusers,true);
        //}else{
        //    $result['state'] = $user['state'];
        //    $result['msgid'] = $user['msgid'];
        //    return $result;
        //}
    }
    # endregion

    # region 红包超时处理 - 强制 - timeOutRedEnveloes
    /**
     * 红包超时处理
     * @param $paras
     * @return mixed
     */
    public static function timeOutRedEnveloesForce($paras)
    {
        global $db;
        global $utility;

        $mastArgs = array(
            'issue',
        );
        $paras = $utility->get_url_args($paras, $mastArgs);
        $paras['nowtime'] = time();

        $db_prefix = \Config\Sys::$dbprefix;
        $result['cmd'] = $paras['cmd'];

        if(empty($paras['issue']))
        {
            $result['state'] = 404;
            $result['msgid'] = 10020;
            return $result;
        }
        //找出当前期数的红包
        $red_data = $db->row("SELECT begintimes,state,overtime FROM `{$db_prefix}bets` WHERE `issue`='{$paras['issue']}' AND `state`=0");
        if(!$red_data){
            $result['state'] = 404;
            $result['msgid'] = 10020;
            return $result;
        }
        //是否超时
        $overtime = (intval($red_data['begintimes']) + intval($red_data['overtime']) - $paras['nowtime']);
        //没有超时时提示
        if($overtime > 0)
        {
            $result['state'] = 404;
            $result['msgid'] = 301; //没有超时时提示指令对数不对
            return $result;
        }
        $game_id = $red_data['gameid'];
        $room_id = \Config\Sys::$gameprefix.$game_id;
        # 找出对应的流水日志
        $db->beginTrans();
            $db->query("UPDATE `" . \Config\Sys::$dbprefix . "bets` SET `state`=2,`isauto`=1 WHERE `issue`='{$paras['issue']}' LIMIT 1");
            //找出所有参与当期红包的帐变记录
            $issue_coinlog = $db->query("SELECT `id`,`gameid`,`ex2`,`uid`,`coin`,`liqtype` FROM `" . \Config\Sys::$dbprefix . "coinlog` WHERE `ex2`='{$paras['issue']}'");
            //开始事务处理============================================
            foreach ($issue_coinlog as $val) {
                $utility->setCoin(array(
                        'uid' => $val['uid'],
                        'coin' => (0 - floatval($val['coin'])), //帐变扣款是负数，返回时须用0去减变回正数
                        'gameid' => $val['gameid'],
                        'liqtype' => $val['liqtype'], //红包超时退回
                        'ex1' => $val['id'],
                        'ex2' => $paras['issue'],
                        'ex3' => '超时退回',
                    )
                );
            }
        $db->commitTrans();
        return array(
            'state' => 200,
            'msgid' => 200,
            'msg' => $paras['issue'].' - 超时退回操作成功',
        );

    }
    # endregion

    # region 发红包准备工作 - sendGameEnvelopes
    public static function sendGameEnvelopes($paras)
    {
        global $db;
        global $redis;
        global $utility;

        $mastArgs = array(
            'token',
            'cmd',
            'room_id|N',
            'game_id|N',
            'coin|F',
            'needuser|N',
            'ws',
            'pass',
            'remoteip'
        );
        $paras = $utility->get_url_args($paras, $mastArgs);

        $result = array();
        $result['cmd'] = $paras['cmd'];

        if(empty($paras['game_id']))
        {
            $result['state'] = 404;
            $result['msgid'] = 10021;
            return $result;
        }
        # 检测用户的token
        if(empty($paras['token'])){
            $result['state'] = 404;
            $result['msgid'] = 10002;
            return $result;
        }

        $user = $utility->exitsToKen($paras['token'],$paras['cmd']);

        if($user['state']==200) {

            if(empty($paras['needuser']) || empty($paras['coin']))
            {
                //指令参数不对
                $result = array(
                    'state'=>404,
                    'msgid'=>301
                );
                return $result;
            }
            //取游戏的基本参数
            $paras['needusernum'] = $paras['needuser'];
            $paras['nowtime'] = time();
            //找出对应游戏的参数
            $game = self::getGameAndOddsForGameID($paras['game_id'], $paras['needusernum']);
            //这里要检测红包的个数是否在指定的范围内
            return self::sendGameEnvelopesBefore($paras['room_id'], $paras, $game, $user);

        }else{
            $result['state'] = $user['state'];
            $result['msgid'] = $user['msgid'];
            return $result;
        }
    }
    # endregion

    # region 发红包前置处理 - sendGameEnvelopesBefore
    /**
     * 发包过程
     * @param $room_id string 房间的ID  game_1
     * @param $client_id string 当前客户端ID
     * @param $paras array 提交的参数列表
     * @param $game array 对应游戏的参数
     * @param $user array 登录成功后对应的用户数据（参见Utility->exitsToKen）
     */
    public static function sendGameEnvelopesBefore($room_id, $paras, $game, $user)
    {
        global $db;
        global $redis;
        global $utility;

        $result = array('state'=>404,'cmd'=>$paras['cmd']);
        # 口令红包的固定费用
        $passcoin = $game['game']['passcoin'];
        //红包的投注金额
        $betCoin = $paras['coin'];
        # 红包的金额
        $redcoin = $betCoin;
        //检测包的数量是否正确
        $testNeedUser = explode(',', $game['game']['manymen']);
        if(!in_array($paras['needusernum'], $testNeedUser))
        {
            $result['msgid'] = 10029;
            return $result;
        }
        //本次发包所需要金币数量(有庄：游戏的人数-1 * $betCoin，无庄：$betCoin)
        //默认为无庄模式
        $betNeedCoin = $betCoin;
        if($game['game']['ishavebanker'])
        {
            //庄家的预计赔注（(人数 -1) * 红包的基本投注 * 最大赔率)）
            //找出游戏的最大赔率( 游戏的赔率是按从大到小的来排序，所以最上面一个就是最大的赔率，后台设置时需要把牌型最大的winsort值最为最大)
            $maxodds = $game['odds'][0]['odds'];

            # 如果有庄但没有固定发包金额的
            $betNeedCoinRed = $game['game']['establishcoin'] > 0 ? $game['game']['establishcoin'] : $betCoin;
            //-----
            $betNeedCoin = (($paras['needusernum'] - 1) * $betCoin * $maxodds);
            #----------------------------------------------------------
            // 如果是扫雷将不按倍数来扣，只核对发包的金额
            if($game['game']['id']==3) $betNeedCoin = 0;
            #----------------------------------------------------------
            // 如果金币余额不足退出发包并提示玩家(创建房间的费用+预计全赔的金额)
            if(($user['usercoin'] - $user['givecoin']) < ($betNeedCoin + $betNeedCoinRed + $passcoin))
            {
                $result['msgid'] = 10005; //金币不足
                $result['givecoin'] = $user['givecoin'];
                return $result;
            }
        }else{
            //如果金币余额不足退出发包并提示玩家(创建房间的费用+预计全赔的金额)
            if(($user['usercoin'] - $user['givecoin']) < ($betCoin + $passcoin))
            {
                $result['msgid'] = 10005; //金币不足
                $result['givecoin'] = $user['givecoin'];
                return $result;
            }
        }

        //如果发送或投注的的金额小于或大于游戏参数设置的值，退出并提示玩家
        if($betCoin < $game['game']['minbetcoin'] || $betCoin > $game['game']['maxbetcoin'])
        {
            $result['msgid'] = 10013;
            $result['max'] = $game['game']['maxbetcoin'];
            $result['min'] = $game['game']['minbetcoin'];
            return $result;
        }
        #region 开始发包记录
        // 产生期号
        $currentIssue = self::getIssue($game['game']['id']);
        # 红包的金额
        if(floatval($game['game']['establishcoin']) > 0)
        {
            $redcoin = floatval($game['game']['establishcoin']);
        }
        //记录发包的记录
        $send_log = array(
            'issue' => $currentIssue,
            'uid' => $user['uid'],
            'nickname' => $user['nickname'],
            'cur' => 1, //一发红包默认就是有自己一个人参与进去
            'coin' => $betCoin, //这里是发包的金币数量，每个人，不是加倍后的 ,红包的投注金额
            'redcoin' => $redcoin, // 红包的金额
            'ip' => $paras['remoteip'],
            'begintimes' => $paras['nowtime'],
            'mantissa' => $paras['ws'],
            'overtime' => $game['game']['overtime'],
            'gameid' => $game['game']['id'],
            'need' => $paras['needusernum'],
            'pass' => (!empty($paras['pass']) ? md5($paras['pass']) : ''),
            'usertype' => $user['usertype'],
        );
        $currentRedEnvelopesID = $db->insert(\Config\Sys::$dbprefix.'bets')->cols($send_log)->query();
        //发包金额，两种模式：有庄和无庄，
        //有庄的需要发一个固定金币的红包
        $db->beginTrans();
        if(floatval($game['game']['establishcoin']) > 0)
        {
            //记录固定发包的帐变
            $utility->setCoin(
                array(
                    'uid' => $user['uid'],
                    'coin' => (0 - floatval($game['game']['establishcoin'])),
                    'gameid' => $game['game']['id'],
                    'liqtype' => 1, //发包扣款
                    'ex1' => $currentRedEnvelopesID,
                    'ex2' => $currentIssue,
                )
            );
        }else{
            # 如果没有固定发包的金额就要扣除，所发红包的金额
            if($game['game']['ishavebanker']==1) {
                $utility->setCoin(
                    array(
                        'uid' => $user['uid'],
                        'coin' => (0 - floatval($betCoin)),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 1, //发包扣款
                        'ex1' => $currentRedEnvelopesID,
                        'ex2' => $currentIssue,
                    )
                );
            }
        }
        # 创建房间所需要扣的暂扣所有玩家赔率金额
        if($betNeedCoin>0) {
            $utility->setCoin(
                array(
                    'uid' => $user['uid'],
                    'coin' => (0 - floatval($betNeedCoin)),
                    'gameid' => $game['game']['id'],
                    'liqtype' => 15, //创建房间
                    'ex1' => $currentRedEnvelopesID,
                    'ex2' => $currentIssue,
                )
            );
        }

        # 如果是口令红包且有固定的口令红包费用
        if(!empty($paras['pass']) AND floatval($passcoin) > 0)
        {
            $utility->setCoin(
                array(
                    'uid' => $user['uid'],
                    'coin' => (0 - floatval($passcoin)),
                    'gameid' => $game['game']['id'],
                    'liqtype' => 28,
                    'ex1' => $currentRedEnvelopesID,
                    'ex2' => $currentIssue,
                )
            );
        }
        //把自己加入到参与抢红包的队列数据中
        $betslog = array(
            'uid' => $user['uid'],
            'issue' => $currentIssue,
            'gameid' => $game['game']['id'],
            'times' => $paras['nowtime'],
            'betcoin' => $send_log['coin'],
        );
        $db->insert(\Config\Sys::$dbprefix.'betslog')->cols($betslog)->query();
        $db->commitTrans();
        #endregion 结束发包动作
        //组织要推送给玩家的数据
        $result['state'] = 200;
        $result['gameid'] = $game['game']['id'];
        $result['groupname'] = \Config\Sys::$gameprefix.$game['game']['id'];
        $result['user'] = $user;
        unset($result['msgid']);
        $result['datas'] = array(
                'id'=> $currentRedEnvelopesID,
                'issue'=> $currentIssue,
                'nickname'=> $user['nickname'],
                'avatar' => $user['avatar'],
                'need' => $paras['needusernum'], //所需要的人数为前台提交的人数，但需在前面进行验证安全性
                'times' => $utility->formatTimes($paras['nowtime']),
                'overtime' => $game['game']['overtime'], //发包时的超时时间即为默认的超时数值
                'cur'=>1,
                'coin'=>$betCoin,
                'mantissa' => (intval($game['game']['id'])==3 ? $paras['ws'] : ''),
                'ispass' => (empty($paras['pass']) ? 0 : 1),
                'usertype' => $user['usertype'],
        );
        //创建新的Redis队列，以红包的期数为Group的ID
        //在Redis队列后面加入新的玩家号码，如果不存在即创建一个新的
        $redis->rpush(\Config\Sys::$redisKey['IISSUE'].$currentIssue, $user['uno']);
        //$redisKey = $this->redis->rpush($currentIssue, $user['uno']);
        //$redisExpire = intval($game['game']['overtime']) + 30;
        //$redisKey.expire($currentIssue, $redisExpire); // 设置过期时间为设定的超时时间加30秒
        //推送给自己
        $result['userscoin'] = $utility->getUserCoinForToken($user['token']); //取用户的余额
        return $result;

    }
    # endregion

    # region 准备抢包 - grabGameEnvelopes
    /**
     * 抢红包前置
     * @param $paras
     * @return mixed
     */
    public static function grabGameEnvelopes($paras)
    {
        global $db;
        global $redis;
        global $utility;

        $mastArgs = array(
            'cmd',
            'room_id',
            'game_id|N',
            'red_issue',
            'pass',
            'token',
        );

        $paras = $utility->get_url_args($paras, $mastArgs);
        $result = array('state'=>404, 'cmd'=>$paras['cmd']);

        $redis_key_count = 0;
        # 期数、游戏种类、用户的token不能为空
        if(empty($paras['red_issue']) || empty($paras['game_id']) || empty($paras['token']))
        {
            $result['state'] = 404;
            $result['msgid'] = 404;
            return $result;
        }
        # 检测用户的token
        if(empty($paras['token'])){
            $result['state'] = 404;
            $result['msgid'] = 10002;
            return $result;
        }
        //如果Redis中没有了以当期红包期数为Key创建的列表即红包为无效
        if(!$redis->exists(\Config\Sys::$redisKey['IISSUE'].$paras['red_issue'])){
            $result['state'] = 404;
            $result['msgid'] = 10016;
            return $result;
        }

        //统计当前期数的人数(要在Redis中统计参与人数)
        $_total = $redis->llen(\Config\Sys::$redisKey['IISSUE'].$paras['red_issue']);
        //找出当前期数的红包
        $red_data = $db->row("SELECT * FROM `".\Config\Sys::$dbprefix."bets` WHERE `issue`='{$paras['red_issue']}' AND `state`=0");
        if(!$red_data){
            $result['state'] = 404;
            $result['msgid'] = 10016;
            return $result;
        }
        if($_total >= $red_data['need']){
            //人数已够，抢包失败
            $result['state'] = 404;
            $result['msgid'] = 10015;
            return $result;
        }
        # 如果红包口令不正确
        if(!empty($red_data['pass'] AND $red_data['pass']!=md5($paras['pass'])))
        {
            $result['state'] = 404;
            $result['msgid'] = 10083;
            return $result;
        }

        $user = $utility->exitsToKen($paras['token'],$paras['cmd']);

        //记录当前时间
        $nowtime = time();
        $paras['nowtime'] = $nowtime;

        if($user['state']==200){
            # 试玩不能抢正常的红包
            if($user['usertype']==0 AND $red_data['usertype'] > 0){
                $result['state'] = 404;
                $result['msgid'] = 10084;
                return $result;
            }
            # 正式用户不能抢试玩的红包
            if($red_data['usertype']==0 AND $user['usertype']>0)
            {
                $result['state'] = 404;
                $result['msgid'] = 10086;
                return $result;
            }
            $uid = $user['uid'];
            /////---------------------------------------------------
            /// 抢红包公共检测事件
            /// ----------------------------------------------------

            //是否超时
            $overtime = (intval($red_data['begintimes']) + intval($red_data['overtime']) - $nowtime);
            //超时处理
            //============================================================
            $paras['overtime'] = $overtime;
            //自己发的红包不需要再抢，默认已在队列中了，直接展示出红包
            //if(!\Config\Sys::$isDebug) {
                if ($red_data['uid'] == $uid) {
                    $result = array(
                        'state' => 200,
                        'cmd' => 'grab',
                        'reddata' => self::getRedPacketForIssue($red_data['issue']),
                        'grabusers' => self::getGrabUserList($red_data['issue']),
                        'usercoin' => $user['usercoin'],
                        'begintimes' => $utility->formatTimes($red_data['begintimes']),
                    );
                    // 格式化日期时间
                    $result['reddata']['begintimes'] = $utility->formatTimes($result['reddata']['begintimes']);

                    foreach ($result['grabusers'] as $k=>$v)
                    {
                        $result['grabusers'][$k]['times'] = $utility->formatTimes($v['times']);
                    }
                    return $result;
                }
            //}
            //*/
            $paras['curusernum'] = $_total;

            //检测当期红包是否已存在这个uid
            $isHaveNuo = false; //初期设定当前UNO不在Redis列表中
            //if(!\Config\Sys::$isDebug) {
                //要在Redis中查找这个UNO是否存在于列表中，如果有就不能再参与了
                $redis_key_index = 0;
                $redis_key_count = $_total;
                while($redis_key_index < $redis_key_count){
                    $redis_key_item = $redis->lindex(\Config\Sys::$redisKey['IISSUE'].$red_data['issue'], $redis_key_index);
                    if($redis_key_item == $user['uno'])
                    {
                        # 已经存在了
                        $isHaveNuo = true;
                    }
                    $redis_key_index++;
                }
                # 当列表中存在这个UNO时直接组织展示数据给前台
                if ($isHaveNuo) {
                    $result = array(
                        'state' => 200,
                        'cmd' => 'grab',
                        'reddata' => self::getRedPacketForIssue($red_data['issue']),
                        'grabusers' => self::getGrabUserList($red_data['issue']),
                        'usercoin' => $user['usercoin'],
                        'begintimes' => $utility->formatTimes($red_data['begintimes']),
                    );
                    // 格式化日期时间
                    $result['reddata']['begintimes'] = $utility->formatTimes($result['reddata']['begintimes']);

                    foreach ($result['grabusers'] as $k=>$v)
                    {
                        $result['grabusers'][$k]['times'] = $utility->formatTimes($v['times']);
                    }
                    if($red_data['gameid']==3){
                        $result['mantissa'] = $red_data['mantissa'];
                    }
                    return $result;
                }
            //}
            //加到Redis队列中
            //$redis->rpush($red_data['issue'], $user['uno']);
            //找出对应游戏的参数
            $game = self::getGameAndOddsForGameID($red_data['gameid'], $red_data['need']);
            return self::grabRedEnvelopesAfter($paras['room_id'], $paras, $game, $red_data, $user);

        }else{
            $result['state'] = $user['state'];
            $result['msgid'] = $user['msgid'];
            return $result;
        }
    }
    # endregion


    #region 抢红包前置 - 准备分流 - grabRedEnvelopesAfter
    /**
     * 抢红包前置 - 准备分流
     * @param $room_id
     * @param $paras
     * @param $game
     * @param $red_data
     * @param $user
     */
    public static function grabRedEnvelopesAfter($room_id, $paras, $game, $redEnvelopes, $user)
    {
        global $db;
        global $redis;
        global $utility;

        $result = array('state'=>404,'cmd'=>$paras['cmd']);
        //红包的投注金额，默认无庄模式
        $betNeedCoin = $redEnvelopes['coin'];
        if($game['game']['ishavebanker'])
        {
            //有庄模式需要按赔率投注
            //闲家的预计赔注（红包的基本投注 * 最大赔率)，闲家只对应庄家一个人的赔注
            $betNeedCoin = ($betNeedCoin * $game['odds'][0]['odds']);
        }

        //检验用户的余额
        if(($user['usercoin'] - $user['givecoin']) < $betNeedCoin)
        {
            $result['msgid'] = 10005;
            return $result;
        }
        # 再次检测队列总数
        $_total = $redis->llen(\Config\Sys::$redisKey['IISSUE'].$redEnvelopes['issue']);
        if($_total >= $redEnvelopes['need']){
            //人数已够，抢包失败
            $result['state'] = 404;
            $result['msgid'] = 10015;
            return $result;
        }
        # 加到Redis队列中
        $redis->rpush(\Config\Sys::$redisKey['IISSUE'].$redEnvelopes['issue'], $user['uno']);
        //记录帐变
        $db->beginTrans();
        $utility->setCoin(array(
            'uid' => $user['uid'],
            'coin' => (0-floatval($betNeedCoin)),
            'gameid' => $game['game']['id'],
            'liqtype' => 2,
            'ex1' => $redEnvelopes['id'],
            'ex2' => $redEnvelopes['issue'],
        ));
        //添加到红包记录(betslog)
        $betslog = array(
            'uid' => $user['uid'],
            'issue' => $redEnvelopes['issue'],
            'gameid' => $game['game']['id'],
            'times' => $paras['nowtime'],
            'betcoin' => $redEnvelopes['coin'],
        );
        $db->insert(\Config\Sys::$dbprefix.'betslog')->cols($betslog)->query();
        //更新当有期抢红包人数
        $db->query("UPDATE `".\Config\Sys::$dbprefix."bets` SET `cur`=`cur`+1 WHERE `issue`='{$redEnvelopes['issue']}' LIMIT 1");
        $db->commitTrans();
        //扣除成功，通知当前房间(room_id)的当前期数红包已新增一个玩家
        //取出当前期数的参与玩家人数（用之前的统计结果加1）
        $paras['curusernum'] = $redis->llen(\Config\Sys::$redisKey['IISSUE'].$redEnvelopes['issue']);
        $update_redEnvelopes_for_issue = array(
            'cmd' => 'updatered',
            'issue' => $redEnvelopes['issue'],
            'cur' => (intval($paras['curusernum'])),
        );

        # 组装通知其它玩家页面的数据
        $result['updatered'] = $update_redEnvelopes_for_issue;
        //通知完成之前的房间后开始准备展示参与玩家的展示页面数据
        $result['state'] = 200;
        //剩余时间 = 红包的超时数 - （当前时间 - 发包的时间）
        $overtime = intval($redEnvelopes['overtime']) - (time() - intval($redEnvelopes['begintimes']));
        //抢包标题、期数、时间
        $result['reddata'] = array(
            'issue' => $redEnvelopes['issue'],
            'begintimes' => $utility->formatTimes($redEnvelopes['begintimes']),
            'overtime' => $overtime,
        );
        //取出当前期数红包参与的所有玩家
        $result['grabusers'] = self::getGrabUserList($redEnvelopes['issue']);
        //更新展示的时间
        $showuser = $result['grabusers'];
        foreach ($showuser as $k=>$v){
            $showuser[$k]['times'] = $utility->formatTimes($showuser[$k]['times']);
        }
        $result['grabusers'] = $showuser;
        $result['user'] = $user;
        //加入到以当前期数为组的Group中
        //Gateway::joinGroup($client_id, $redEnvelopes['issue']);

        //通知加到到Group的玩家更新页面
        $Group_Result = array(
            'state' => 200,
            'cmd' => 'newsjoingrab',
            'issue' => $redEnvelopes['issue'],
            'datas' => array(
                'gameid' => $redEnvelopes['gameid'],
                'coin' => $redEnvelopes['coin'],
            ),
            'grabusers' => $showuser,
        );
        if(intval($redEnvelopes['gameid'])==3)
        {
            $Group_Result['datas']['mantissa'] = $redEnvelopes['mantissa'];
        }
        $result['groupname'] = \Config\Sys::$gameprefix . $game['game']['id'];
        $result['newsjoingrab'] = $Group_Result;
        //Gateway::sendToGroup($redEnvelopes['issue'], json_encode($Group_Result));
        //组织当前玩家的展示页面数据
        //$result['overtime'] = $overtime;
        //刷新当前用户的余额
        $result['usercoin'] = $utility->getUserCoinForToken($user['token']);
        //Gateway::sendToCurrentClient(json_encode($result));

        //如果参与的玩家人数已达到当期红包设定的人数即直接开奖
        //echo "需要人数：{$redEnvelopes['need']}，参与人数：{$update_redEnvelopes_for_issue['cur']} \n";

        if(intval($update_redEnvelopes_for_issue['cur']) >= intval($redEnvelopes['need']) && count($showuser) >= intval($redEnvelopes['need']))
        {
            if(!$redis->exists(\Config\Sys::$redisKey['IISSUE'].$redEnvelopes['issue'])){
                return array('state'=>404,'msgid'=>404);
            }
            # 如果已经已经作了超时就不要再进行这个结算了
            # 2018-01-11 2:54
            $gameover_redis_key = \Config\Sys::$redisKey['GISSUE'].$paras['red_issue'].'_gameover';
            if($redis->exists($gameover_redis_key.'_timeout'))
            {
                return $result;
            }else{
                if($redis->exists($gameover_redis_key))
                {
                    //print_r('游戏完成：' . $gameover_redis_key . ' -- 其它进程已处理结算' . "\n");
                    return $result;
                }else {
                    $isSet = $utility->redisSetEx($gameover_redis_key, 1, 120);
                    //print_r('游戏完成：' . $gameover_redis_key . ' -- ' . $isSet . "\n");
                }
            }
            # 如果已经开始了结算也不再结算

            $setTlement = self::grabRedEnvelopesOver($room_id, $game, $redEnvelopes, $result['grabusers'],false);
            $result['state'] = 200;
            $result['settlement'] = $setTlement;
            return $result;
        }else{
            return $result;
        }
    }
    # endregion

    # region 抢红包结束 - 准备开奖工作 -grabRedEnvelopesOver
    /**
     * 抢包人数已经达到，准备开奖工作
     * @param $room_id
     * @param $paras
     * @param $game
     * @param $redEnvelopes
     * @param $user
     * @param $grabusers
     */
    private static function grabRedEnvelopesOver($room_id, $game, $redEnvelopes, $grabUsers, $isTimeOut)
    {
        global $db;
        global $redis;
        global $utility;

        if(!$redis->exists(\Config\Sys::$redisKey['IISSUE'].$redEnvelopes['issue'])){
            //echo \Config\Sys::$redisKey['IISSUE'].$redEnvelopes['issue'];
            return array('state'=>404,'msgid'=>404);
        }
        //删除对应的Redis中的Key
        $redis->delete(\Config\Sys::$redisKey['IISSUE'].$redEnvelopes['issue']);
        # 取人数
        //$curusernum = $redis->llen(\Config\Sys::$redisKey['IISSUE'].$redEnvelopes['issue']);

        $isOver = (count($grabUsers) >= $redEnvelopes['need']) ? true : false;
        $usedtimes = time() - $redEnvelopes['begintimes'];

        # region 超时处理
        if($isTimeOut && !$isOver)
        {
            //时间到了，没有达到参与人数，退回对应的参与金币
            //退回所有的抢包本金
            //当前红包作废处理

            $db->query("UPDATE `" . \Config\Sys::$dbprefix . "bets` SET `state`=2,`isauto`=1 WHERE `issue`='{$redEnvelopes['issue']}' LIMIT 1");
            //找出所有参与当期红包的帐变记录
            $issue_coinlog = $db->query("SELECT `uid`,`coin`,`liqtype` FROM `" . \Config\Sys::$dbprefix . "coinlog` WHERE `ex2`='{$redEnvelopes['issue']}'");
            //开始事务处理============================================
            $db->beginTrans();
            foreach ($issue_coinlog as $val) {
                $utility->setCoin(array(
                        'uid' => $val['uid'],
                        'coin' => (0 - floatval($val['coin'])), //帐变扣款是负数，返回时须用0去减变回正数
                        'gameid' => $game['game']['id'],
                        'liqtype' => $val['liqtype'], //红包超时退回
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                        'ex3' => '超时退回',
                    )
                );
            }
            $db->commitTrans();
            //事务处理结束==============================================
            //通知组员超时取消当前期数红包
            $game_time_out = array(
                'cmd' => 'game_time_out',
                'issue' => $redEnvelopes['issue'],
                'msgid' => 10024,
                'cur' => $redEnvelopes['need'], //将需要的人数变成当前参与人数，配合前台删除列表
            );
            //通知参与当期红包的用户，超时取消了
            $result['timeoutdata'] = $game_time_out;
            //Gateway::sendToGroup($redEnvelopes['issue'], json_encode($result));
            //通知当前游戏房间的用户，删除指定期数的红包
            $game_time_out['cmd'] = 'updatered';
            unset($result['msgid']);
            //Gateway::sendToGroup($this->gamePrefix.$game['game']['id'], json_encode($result));
            $result['delred'] = $game_time_out;
            $result['state'] = 200;
            $result['room_name'] = \Config\Sys::$gameprefix . $game['game']['id'];
            return $result;
        }
        # endregion

        # region 超时（不超时）人数已达到
        if(!$isTimeOut && $isOver)
        {
            $nowtime = time();
            $db->query("UPDATE `".\Config\Sys::$dbprefix."bets` SET `endtimes`={$nowtime},`usedtimes`={$usedtimes}, `state`=1,`isauto`=1 WHERE `issue`='{$redEnvelopes['issue']}' LIMIT 1");
            //预先分配红包
            $redpackets_coin = $redEnvelopes['coin'];
            //如果有设置发固定红包金额的，需按这个金额来分配红包 $game['game']['establishcoin']
            if(intval($game['game']['establishcoin'])>0) $redpackets_coin = $game['game']['establishcoin'];
            //产生红包数据
            $roundRedPackets = $utility->redPacketRound($redpackets_coin, $redEnvelopes['need']);
            //开始玩法输赢算法
            $calculationFunc = 'game_calculation_'.$game['game']['func'];
            $enddata = self::$calculationFunc($room_id, $game, $grabUsers, $redEnvelopes, $roundRedPackets, $usedtimes);

            # 处理用户的VIP升级
            if(isset($enddata['userscoin'])) {
                $betCoin = $redEnvelopes['coin'];
                foreach ($enddata['userscoin'] as $uno=>$usercoin) {
                    $sql = 'UPDATE `' . \Config\Sys::$dbprefix . 'users` SET `betcoin`=`betcoin`+' . $betCoin . ' WHERE `uno`=\'' . $uno . '\' LIMIT 1';
                    $db->query($sql);
                    # 找出上级代理
                }
                //$db->beginTrans();
                //组装批量更新SQL
                //$update_sql = $utility->batchUpdateTable(\Config\Sys::$dbprefix.'betslog','id',$idsValue);
                //$db->query($update_sql);
                //$db->commitTrans();
            }
            if(isset($enddata['grabusers']))
            {
                $db->beginTrans();
                foreach ($enddata['grabusers'] AS $k=>$v)
                {
                    $ticket_winer = abs(($v['ticket'] + $v['winerprofit']));
                    //赠送积分
                    $utility->setScore(
                        array(
                            'uid' => $v['uid'],
                            'score' => floatval($redEnvelopes['coin']),
                            'gameid' => $game['game']['id'],
                            'liqtype' => 1, //创建房间
                            'ex1' => $redEnvelopes['id'],
                            'ex2' => $redEnvelopes['issue'],
                        )
                    );

                    if($ticket_winer > 0){
                        # 找出上级代理
                        $sql = 'SELECT `parentid`,`backtotal` FROM `'.\Config\Sys::$dbprefix.'users` WHERE `uid`='.$v['uid'].' LIMIT 1';
                        $parentid = $db->row($sql);
                        $userbacktotal = $parentid['backtotal'];
                        $parentid = $parentid['parentid'];
                        if(!empty($parentid)) {
                            $sql = 'SELECT `agentlevel` FROM `' . \Config\Sys::$dbprefix . 'users` WHERE `uid`=' . $parentid . ' LIMIT 1';
                            $agentlevel = $db->row($sql);
                            $agentlevel = $agentlevel['agentlevel'];

                            $sql = 'SELECT `lid`,`backtotal`,`backposion` FROM `' . \Config\Sys::$dbprefix . 'agentlevel` WHERE `lid`=' . $agentlevel . ' LIMIT 1';
                            $agent = $db->row($sql);
                            $agentbacktotal = $agent['backtotal'];
                            $backposion = $agent['backposion'];

                            $backcoin = $utility->formatCoin(($ticket_winer * $backposion / 100));
                            # print_r($backcoin);
                            if (floatval($backcoin) > 0 && intval($redEnvelopes['usertype'])>0) {
                                $utility->setCoin(
                                    array(
                                        'uid' => $parentid,
                                        'coin' => floatval($utility->formatCoin($backcoin)),
                                        'gameid' => $game['game']['id'],
                                        'liqtype' => 24, //抽水
                                        'ex1' => $v['id'],
                                        'ex2' => $enddata['issue'],
                                        'ex3' => $v['nickname'] . '(' . $ticket_winer . '×' . $backposion . '%)',
                                    )
                                );
                            }
                            # 处理上级用户的代理升级

                        }
                    }
                }
                $db->commitTrans();
            }
            return $enddata;
        }
        # endregion
    }
    # endregion

    # region 红包结算 - 算法

    # region 1 - 比大小
    /** 五人对战
     * @param $room_id string 房号
     * @param $game array 游戏及赔率的信息(game, odds)
     * @param $grabUsers array 参与的玩家
     * @param $redEnvelopes array 本期红包
     * @param $roundRedPackets array 分配好的红包金额
     * @param $usedtimes int 抢完本期红包所花的时间
     */
    private static function game_calculation_wrdz($room_id, $game, $grabUsers, $redEnvelopes, $roundRedPackets, $usedtimes)
    {
        global $db;
        global $redis;
        global $utility;

        $user_ids = "0";
        $betodds = $game['odds'][0];
        $issue = $redEnvelopes['issue'];
        //门票的点数
        $ticket = isset($betodds['ticket']) ? $betodds['ticket'] : 3;
        $bankerwon_profit = isset($betodds['winerprofit']) ? $betodds['winerprofit'] : 0;
        # 找出抢到的红包金币数量是最大和最小的玩家

        $idsValue = array();
        //分配红包给用户，并记住最大红包的UNO(UID)和最小红包的UNO(UID)
        $maxCoinUser = array('uid'=>0, 'coin'=>0);
        $minCoinUser = array('uid'=>0, 'coin'=>$redEnvelopes['coin']);
        //发红包的玩家（庄家）
        //$bankerUser = $grabUsers[0];
        $grabUsersLen = count($grabUsers)-1;
        for($k=$grabUsersLen; $k>=0; $k--){
            $v = $grabUsers[$k];
        //foreach ($grabUsers as $k=>$v){
            $args = array(
                'mantissa' => $redEnvelopes['mantissa'],
                'uid' => $v['uid'],
                'gameid' => $redEnvelopes['gameid'],
                'usertype' => $redEnvelopes['usertype'],
                'odds' => $game['odds'],
            );
            $arr = $utility->getRedPacketFromArray($roundRedPackets, $args);
            $ticketcoin = $utility->formatCoin($arr['coin'] * $ticket / 100);
            $idsValue[$k] = array(
                'id' => $v['id'],
                'value' => array(
                    'coin' => $arr['coin'],
                    'ticket' => $ticketcoin,
                    'winerprofit' => 0,
                    'profit' => 0,
                    'usedtimes' => $usedtimes,
                    'odds' => $betodds['odds'],
                    'state' => 1,
                )
            );
            //更新到用户抢包记录中
            $grabUsers[$k]['coin'] = $arr['coin'];
            $grabUsers[$k]['odds'] = $betodds['odds'];
            $grabUsers[$k]['ticket'] = $ticketcoin;

            //重新组织红包数据，这个数据是删除刚刚取出那行后的新数据
            $roundRedPackets = $arr['redpackets'];

            if($arr['coin'] > $maxCoinUser['coin'])
            {
                $maxCoinUser = array('uid'=>$v['uid'], 'coin'=>$arr['coin']);
            }
            if($arr['coin'] < $minCoinUser['coin'])
            {
                $minCoinUser = array('uid'=>$v['uid'], 'coin'=>$arr['coin']);
            }
            if($arr['coin'] == $minCoinUser['coin'])
            {
                $minCoinUser = array('uid'=>$v['uid'], 'coin'=>$arr['coin']);
            }
            $user_ids .= ",".$v['uid'];
        }

        //找出扣款（发包和抢包）的流水记录并返还(除抢到最小红包)
        //print_r($minCoinUser);

        $db->beginTrans();
        foreach ($grabUsers as $key=>$v)
        {
            //记录抢到的红包帐变
            $utility->setCoin(array(
                'uid' => $v['uid'],
                'gameid' => $v['gameid'],
                'coin' => $v['coin'],
                'liqtype' => 7,
                'ex1' => $redEnvelopes['id'],
                'ex2' => $redEnvelopes['issue'],
            ));

            //本金除抢到的最小红包玩家外全部退回 ，同时抽水
            if($v['uid']!=$minCoinUser['uid']) {
                # 返还预投注
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => $redEnvelopes['coin'],
                        'gameid' => $game['game']['id'],
                        'liqtype' => 9,
                        'ex1' => $v['id'],
                        'ex2' => $issue,
                    )
                );
            }
                //收取玩家门票
                if($v['ticket'] >0) {
                    $utility->setCoin(
                        array(
                            'uid' => $v['uid'],
                            'coin' => (0 - floatval($v['ticket'])),
                            'gameid' => $game['game']['id'],
                            'liqtype' => 8,
                            'ex1' => $v['id'],
                            'ex2' => $v['issue'],
                            'ex3' => $v['coin'] . '×' . $ticket . '%',
                        )
                    );
                }
                # 抽水
                $winerprofit = $utility->formatCoin(floatval($v['coin']) * floatval($bankerwon_profit) / 100);
                if(floatval($winerprofit) > 0) {
                    $utility->setCoin(
                        array(
                            'uid' => $v['uid'],
                            'coin' => (0 - floatval($winerprofit)),
                            'gameid' => $game['game']['id'],
                            'liqtype' => 10,
                            'ex1' => $redEnvelopes['id'],
                            'ex2' => $issue,
                            'ex3' => $v['coin'] . '×' . $bankerwon_profit . '%',
                        )
                    );
                    $grabUsers[$key]['winerprofit'] = $winerprofit;
                    $idsValue[$key]['value']['winerprofit'] = $winerprofit;
                }

            //}
        }
        $db->commitTrans();

        //组织前台页面展示数据
        foreach($grabUsers as $k=>$v) {
            unset($grabUsers[$k]['issue']);
            unset($grabUsers[$k]['gameid']);
            unset($grabUsers[$k]['cardtype']);
            unset($grabUsers[$k]['mantissa']);
            unset($grabUsers[$k]['odds']);
            unset($grabUsers[$k]['userid']);
            //最终盈利

            # 抢到最小金额红包者
            if($v['uid']==$minCoinUser['uid']){
                //echo '最小红包是：'.$v['uid'];
                $profit = $grabUsers[$k]['coin'] - $redEnvelopes['coin'] - $grabUsers[$k]['ticket'] - $grabUsers[$k]['winerprofit'];
            }else{
                $profit = $grabUsers[$k]['coin'] - $grabUsers[$k]['ticket'] - $grabUsers[$k]['winerprofit'];
            }
            $grabUsers[$k]['betcoin'] = $redEnvelopes['coin'];
            $grabUsers[$k]['ecoin'] = $game['game']['establishcoin']; //创建的红包的固定金额（固定费用）
            $grabUsers[$k]['ecost'] = $game['game']['establishcost']; //参与游戏的费用，固定费用（包底）
            $grabUsers[$k]['profit'] = $utility->formatCoin($profit);
            $idsValue[$k]['value']['profit'] = $grabUsers[$k]['profit'];
            //牌型名称
            $grabUsers[$k]['cardtitle'] = '';
            //$grabUsers[$k]['times'] = $utility->formatTimes($grabUsers[$k]['times']);
        }
        $db->beginTrans();
        //组装批量更新SQL
        $update_sql = $utility->batchUpdateTable(\Config\Sys::$dbprefix.'betslog','id',$idsValue);
        $db->query($update_sql);
        $db->commitTrans();

        //重新排序，按抢到红包从大到小排
        $utility->sortArray($grabUsers, 'coin', 'ASC');

        $result = array(
            'state' => 200,
            'cmd' => 'gameover',
            'reddata' => array(),
            'mantissa' => '',
            'bankercoin' => $game['game']['establishcoin'],
            'betcoin' => $redEnvelopes['coin'],
            'ecoin' => $game['game']['establishcoin'], //创建的红包的固定金额（固定费用）
            'ecost' => $game['game']['establishcost'], //参与游戏的费用，固定费用（包底）
            'usedtimes' => $usedtimes, //所花时间
            'needuser' => $redEnvelopes['need'],
            'grabusers' => $grabUsers,
            'times' => $utility->formatTimes($redEnvelopes['begintimes']),
            'issue' => $redEnvelopes['issue'],
            'room_name' => \Config\Sys::$gameprefix . $game['game']['id'],
            'userscoin' => $utility->sendToUidFreeCoinForIssue($grabUsers),
        );
        //Gateway::sendToGroup($redEnvelopes['issue'], json_encode($result));
        //取出列表用户的余额数据并推送
        //$result['userscoin'] = $utility->sendToUidFreeCoinForIssue($grabUsers);
        return $result;
    }
    # endregion

    # region 2 - 牛牛
    /** 牛牛
     * @param $room_id string 房号
     * @param $game array 游戏及赔率的信息(game, odds)
     * @param $grabUsers array 参与的玩家
     * @param $redEnvelopes array 本期红包
     * @param $roundRedPackets array 分配好的红包金额
     * @param $usedtimes int 抢完本期红包所花的时间
     */
    private static function game_calculation_nn($room_id, $game, $grabUsers, $redEnvelopes, $roundRedPackets, $usedtimes)
    {
        global $db;
        global $redis;
        global $utility;
        # 分配红包
        $user_ids = "0"; # 参与的用户UID列表
        $betodds = $game['odds'][0];
        $ticket = isset($betodds['ticket']) ? $betodds['ticket'] : 3;
        //找出庄家 - 第一个，最早参与的就是庄家
        //$bankerUser = $grabUsers[0];
        //计算当前参与玩家的最大赔率金额
        $maxBetCoin = $redEnvelopes['coin'] * $game['odds'][0]['odds'];
        //计算庄家预付的最大赔率金额
        $bankerUser_maxBetCoin = $maxBetCoin * ($redEnvelopes['need'] - 1);

        //庄家赢的总金额(以备收门票和抽水),闲家赢的每玩家分次收取
        $bankerUser_win_coin_total = 0;
        $bankerUser_los_coin_total = 0;
        /*
         * 牛牛：后面两位数相加 = 0
         * 对子：后面两位数相同
         * 牛几：后面两位数不是对子也不是牛牛，即比点数大小了
         */
        $db->beginTrans();
        $grabUsersLen = count($grabUsers) - 1;
        for($k=$grabUsersLen; $k>=0; $k--){
            $v = $grabUsers[$k];
            //foreach ($grabUsers as $k=>$v)
            //{
            $args = array(
                'mantissa' => $redEnvelopes['mantissa'],
                'uid' => $v['uid'],
                'gameid' => $redEnvelopes['gameid'],
                'usertype' => $redEnvelopes['usertype'],
                'odds' => $game['odds'],
            );
            $arr = $utility->getRedPacketFromArray($roundRedPackets, $args);
            # 用分配到的红包金额来计算牌型 =============================================================================================
            $coin = strval(number_format($arr['coin'], 2, '.', ''));
            $n1 = substr($coin,-2,1); //小数点第一位
            $n2 = substr($coin,-1);   //小数点后二位

            $winsort_odds_key = 'n'.(($n1+$n2) % 10); // 牛几

            // 最后是最大的牌型：牛牛
            if((($n1+$n2) % 10)==0){
                $winsort_odds_key = "n0";
            }
            # ======================================================================================================
            //找出对应输赢的牌型顺序
            $grabUsers[$k]['winsort'] = $utility->getOddsWinSort($game['odds'],'cardtype', $winsort_odds_key, 'winsort');
            //找出对应的赔率
            $grabUsers[$k]['odds'] = $utility->getOddsWinSort($game['odds'],'cardtype', $winsort_odds_key, 'odds');
            //牌型名称
            $grabUsers[$k]['cardtitle'] = $utility->getOddsWinSort($game['odds'],'cardtype', $winsort_odds_key, 'cardtitle');
            //计算门票
            //$ticketcoin = $this->utility->formatCoin(($redEnvelopes['coin'] * $grabUsers[$k]['odds'] * $ticket) / 100);

            //记录抢到的红包帐变
            $utility->setCoin(array(
                'uid' => $v['uid'],
                'gameid' => $v['gameid'],
                'coin' => $arr['coin'],
                'liqtype' => 7,
                'ex1' => $redEnvelopes['id'],
                'ex2' => $redEnvelopes['issue'],
            ));

            //更新到用户抢包记录中
            $grabUsers[$k]['coin'] = $arr['coin'];
            //$grabUsers[$k]['odds'] = $betodds['odds'];
            $grabUsers[$k]['ticket'] = 0;
            $grabUsers[$k]['winerprofit'] = 0;
            $grabUsers[$k]['cardtype'] = $winsort_odds_key;

            $idsValue[$k] = array(
                'id' => $v['id'],
                'value' => array(
                    'coin' => $arr['coin'],
                    'ticket' => 0,
                    'profit' => 0,
                    'odds' => $grabUsers[$k]['odds'],
                    'cardtype' => $winsort_odds_key,
                    'winsort' => $grabUsers[$k]['winsort'],
                    'winerprofit' => 0,
                    'usedtimes' => $usedtimes,
                    'state' => 1,
                )
            );


            $user_ids .= ",".$v['uid'];

            $roundRedPackets = $arr['redpackets'];
        }
        $db->commitTrans();
        //找出庄家 - 第一个，最早参与的就是庄家
        $bankerUser = $grabUsers[0];
        //找出闲家(第一个是庄家，其它的都是跟抢的闲家)
        $otherUsers = $grabUsers;
        unset($otherUsers[0]);

        //找出庄家后开始与其它玩家进行对比
        $db->beginTrans();
        foreach($otherUsers as $k=>$v)
        {
            //默认是庄家赢
            $winer = array(
                'uid' => $bankerUser['uid'],
                'cardtype' => $bankerUser['cardtype'],
                'wincoin' => ($redEnvelopes['coin'] * $bankerUser['odds']), //默认按最大赔率支付
            );
            //庄家赢的标志
            $banker_win = true;
            //比牌型,winsort的值,如果winsort的值一样，即比进入的时间
            if($v['winsort']==$bankerUser['winsort'])
            {
                //如果两个人的牌型一样,即比拿到的金额大小
                if($v['coin'] > $bankerUser['coin']){
                    $winer['uid'] = $v['uid'];
                    $banker_win = false;
                }
            }else{
                //如果闲家的牌型比庄家的好
                if($v['winsort'] > $bankerUser['winsort'])
                {
                    $winer['uid'] = $v['uid'];
                    $banker_win = false;
                }
            }
            if($banker_win)
            {
                //庄家赢
                //庄家要收取的金币 = （用户的预投注金额 - （投注本额 * 赢家的最终赔率））
                //闲家要收回的金币 = 玩家的预投注金额 - 庄家收取的金币额
                $banker_win_coin = $redEnvelopes['coin'] * $bankerUser['odds'];
                $bankerUser_win_coin_total += $banker_win_coin;
                //记录赢到的金币帐变
                $utility->setCoin(
                    array(
                        'uid' => $winer['uid'],
                        'coin' => floatval($banker_win_coin),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 11,
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                    )
                );

                //如果庄家的赔率不是最大倍率，还要将余下的金币退回给参与玩家
                if($maxBetCoin - $banker_win_coin > 0 ){
                    $utility->setCoin(
                        array(
                            'uid' => $v['uid'],
                            'coin' => floatval($maxBetCoin - $banker_win_coin),
                            'gameid' => $game['game']['id'],
                            'liqtype' => 16,
                            'ex1' => $redEnvelopes['id'],
                            'ex2' => $redEnvelopes['issue'],
                        )
                    );
                }

                //赢家统一在后面($bankerUser_win_coin_total)计算抽水
                //$winerprofit_coin = $game['game'][0]['winerprofit']  * $banker_win_coin;
            }else{
                //退回闲家的预投注金额
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => floatval($maxBetCoin),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 9, //赢家，退回对应预投注的红包
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                    )
                );
                //按赔率计算赢到的金额
                # 2018-01-06 10:16
                # $user_win_coin = $utility->formatCoin($redEnvelopes['coin'] * $v['odds']);
                $user_win_coin = $utility->formatCoin($redEnvelopes['coin'] * $v['odds']);
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => floatval($user_win_coin),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 11, //赢到的金币
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                        'ex3' => $redEnvelopes['coin'] . '×' . $v['odds'] . '倍',
                    )
                );
                //交门票
                //闲家赢 - 门票
                $ticketcoin = $utility->formatCoin((($user_win_coin + $v['coin']) * $ticket) / 100);
                if(floatval($ticketcoin) > 0) {
                    $utility->setCoin(
                        array(
                            'uid' => $v['uid'],
                            'coin' => (0 - floatval($ticketcoin)),
                            'gameid' => $game['game']['id'],
                            'liqtype' => 8, //赢到的金币要交门票
                            'ex1' => $redEnvelopes['id'],
                            'ex2' => $redEnvelopes['issue'],
                            'ex3' => ($user_win_coin + $v['coin']) . '×' . $ticket . '%',
                        )
                    );
                }
                $otherUsers[$k]['ticket'] =  $ticketcoin;

                //赢家抽水
                $winerprofit = $utility->formatCoin((($user_win_coin + $v['coin']) * $game['odds'][0]['winerprofit']) / 100);
                if(floatval($winerprofit) > 0) {
                    $utility->setCoin(
                        array(
                            'uid' => $v['uid'],
                            'coin' => (0 - floatval($winerprofit)),
                            'gameid' => $game['game']['id'],
                            'liqtype' => 10, //赢到的金币要进行抽水
                            'ex1' => $redEnvelopes['id'],
                            'ex2' => $redEnvelopes['issue'],
                            'ex3' => ($user_win_coin + $v['coin']) . '×' . $game['odds'][0]['winerprofit'] . '%',
                        )
                    );
                }
                $otherUsers[$k]['winerprofit'] =  $winerprofit;

                $bankerUser_los_coin_total += $user_win_coin;
            }
        }
        $db->commitTrans();

        //庄家赢利门票及抽水及把余下的预投注还给庄家
        $bankerUser_win_ticket = 0;
        $bankerUser_win_profit = 0;

        $db->beginTrans();
        if($bankerUser_win_coin_total > 0)
        {
            //门票
            $bankerUser_win_ticket = (($bankerUser_win_coin_total + $bankerUser['coin']) *  floatval($game['odds'][0]['ticket'])) / 100;
            $bankerUser_win_ticket = $utility->formatCoin($bankerUser_win_ticket);
            if(floatval($bankerUser_win_ticket) > 0) {
                $utility->setCoin(
                    array(
                        'uid' => $bankerUser['uid'],
                        'coin' => (0 - floatval($bankerUser_win_ticket)),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 8, //赢到的金币要交门票
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                        'ex3' => ($bankerUser_win_coin_total + $bankerUser['coin']) . '×' . $game['odds'][0]['ticket'] .'%',
                    )
                );
            }
            $bankerUser['ticket'] = $bankerUser_win_ticket;
            //抽水
            $bankerUser_win_profit = (($bankerUser_win_coin_total + $bankerUser['coin']) *  floatval($game['odds'][0]['winerprofit'])) / 100;
            $bankerUser_win_profit = $utility->formatCoin($bankerUser_win_profit);
            if(floatval($bankerUser_win_profit) > 0) {
                $utility->setCoin(
                    array(
                        'uid' => $bankerUser['uid'],
                        'coin' => (0 - floatval($bankerUser_win_profit)),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 10, //赢到的金币抽水
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                        'ex3' => ($bankerUser_win_coin_total + $bankerUser['coin']) . '×' . $game['odds'][0]['winerprofit'] .'%',
                    )
                );
            }
            $bankerUser['winerprofit'] = $bankerUser_win_profit;
            $bankerUser['ticket'] = $bankerUser_win_ticket;
        }
        //把余款还给庄家
        $back_bankerUser_coin = $bankerUser_maxBetCoin - $bankerUser_los_coin_total;
        if($back_bankerUser_coin > 0){
            $utility->setCoin(
                array(
                    'uid' => $bankerUser['uid'],
                    'coin' => floatval($back_bankerUser_coin),
                    'gameid' => $game['game']['id'],
                    'liqtype' => 16, //庄家还有预投注的余额，退回
                    'ex1' => $redEnvelopes['id'],
                    'ex2' => $redEnvelopes['issue'],
                )
            );
        }
        # 更新betslog的记录
        foreach ($grabUsers as $k=>$v)
        {
            $profit = 0;
            $ticket = 0;
            //如果是庄家
            if($v['uid']==$bankerUser['uid'])
            {
                $idsValue[$k]['value']['ticket'] = $bankerUser_win_ticket;
                $idsValue[$k]['value']['winerprofit'] = $bankerUser_win_profit;
                $grabUsers[$k]['ticket'] = $bankerUser_win_ticket;
                $grabUsers[$k]['winerprofit'] = $bankerUser_win_profit;

                $betNeedCoin = $game['game']['establishcoin'];

                if ($game['game']['ishavebanker']) {
                    //庄家的预计赔注（(人数 -1) * 红包的基本投注 * 最大赔率)）
                    //找出游戏的最大赔率( 游戏的赔率是按从大到小的来排序，所以最上面一个就是最大的赔率，后台设置时需要把牌型最大的winsort值最为最大)
                    $maxodds = $game['odds'][0]['odds'];
                    $betNeedCoin = (($redEnvelopes['need'] - 1) * $redEnvelopes['coin'] * $maxodds);
                }
                $profit = $bankerUser_win_coin_total - $bankerUser_los_coin_total + $v['coin'] - $grabUsers[$k]['ticket'] - $grabUsers[$k]['winerprofit'];

                $grabUsers[$k]['issue_usertype'] = 1;
            }else{
                //其它的就是闲家了
                foreach ($otherUsers as $ok=>$ov)
                {
                    if($v['uid']==$ov['uid'])
                    {
                        $idsValue[$k]['value']['ticket'] = $otherUsers[$ok]['ticket'];
                        $idsValue[$k]['value']['winerprofit'] = $otherUsers[$ok]['winerprofit'];
                        $grabUsers[$k]['ticket'] = $otherUsers[$ok]['ticket'];
                        $grabUsers[$k]['winerprofit'] = $otherUsers[$ok]['winerprofit'];

                        //如果庄家赢
                        if($v['winsort'] < $bankerUser['winsort'])
                        {
                            //按庄家的赔率来计算(最大预投注 - 赔给庄家的金币 - 门票 - 抽水)
                            $profit = $v['coin'] - ($bankerUser['odds'] * $redEnvelopes['coin']) - $otherUsers[$ok]['ticket'] - $otherUsers[$ok]['winerprofit'];
                        }
                        //闲家赢
                        if($v['winsort'] > $bankerUser['winsort']){
                            //按闲家的赔率来计算(最大预投注 - 赔给庄家的金币 - 门票 - 抽水)
                            $profit = ($otherUsers[$ok]['odds'] * $redEnvelopes['coin']) + $otherUsers[$ok]['coin'] - $otherUsers[$ok]['ticket'] - $otherUsers[$ok]['winerprofit'];
                        }
                        //如果winsort相同，对比金额
                        if($v['winsort'] == $bankerUser['winsort']) {
                            if ($v['coin'] > $bankerUser['coin']) {
                                $profit = ($otherUsers[$ok]['odds'] * $redEnvelopes['coin']) + $otherUsers[$ok]['coin'] - $otherUsers[$ok]['ticket'] - $otherUsers[$ok]['winerprofit'];
                            }else{
                                $profit = $v['coin'] - ($bankerUser['odds'] * $redEnvelopes['coin']) - $otherUsers[$ok]['ticket'] - $otherUsers[$ok]['winerprofit'];
                            }
                        }
                        $grabUsers[$k]['issue_usertype'] = 0;
                    }
                }
            }
            //最终盈利
            $grabUsers[$k]['profit'] = $utility->formatCoin($profit);
            $idsValue[$k]['value']['ticket'] = $grabUsers[$k]['ticket'];
            $idsValue[$k]['value']['profit'] = $grabUsers[$k]['profit'];

            unset($grabUsers[$k]['issue']);
            unset($grabUsers[$k]['gameid']);
            unset($grabUsers[$k]['mantissa']);
            unset($grabUsers[$k]['odds']);
            unset($grabUsers[$k]['userid']);
            unset($grabUsers[$k]['mantissa']);
            //$grabUsers[$k]['times'] = $utility->formatTimes($grabUsers[$k]['times']);
        }
        //更新betslog数据库
        $update_sql = $utility->batchUpdateTable(\Config\Sys::$dbprefix.'betslog', 'id', $idsValue);
        $db->query($update_sql);
        $db->commitTrans();

        $result = array(
            'state' => 200,
            'cmd' => 'gameover',
            'reddata' => array(),
            'mantissa' => '',
            'bankercoin' => $betNeedCoin,
            'betcoin' => $redEnvelopes['coin'],
            'ecoin' => $game['game']['establishcoin'], //创建的红包的固定金额（固定费用）
            'ecost' => $game['game']['establishcost'], //参与游戏的费用，固定费用（包底）
            'usedtimes' => $usedtimes, //所花时间
            'needuser' => $redEnvelopes['need'],
            'grabusers' => $grabUsers,
            'times' => $utility->formatTimes($redEnvelopes['begintimes']),
            'issue' => $redEnvelopes['issue'],
            'room_name' => \Config\Sys::$gameprefix . $game['game']['id'],
            'userscoin' => $utility->sendToUidFreeCoinForIssue($grabUsers),
        );
        return $result;
        //Gateway::sendToGroup($redEnvelopes['issue'], json_encode($result));
        //取出列表用户的余额数据并推送
        //$result['userscin'] = $utility->sendToUidFreeCoinForIssue($grabUsers);
        //结算数据推送给当期玩家
    }
    # endregion

    # region 3 - 旧扫雷
    /** 扫雷
     * @param $room_id string 房号
     * @param $game array 游戏及赔率的信息(game, odds)
     * @param $grabUsers array 参与的玩家
     * @param $redEnvelopes array 本期红包
     * @param $roundRedPackets array 分配好的红包金额
     * @param $usedtimes int 抢完本期红包所花的时间
     */
    private static function game_calculation_sl_old($room_id, $game, $grabUsers, $redEnvelopes, $roundRedPackets, $usedtimes)
    {
        global $db;
        global $redis;
        global $utility;

        $issue = $redEnvelopes['issue'];
        //取出当前玩家的赔率（按人数来区分，7人1.5倍，10人1倍）
        $betodds = $game['odds'][0]; //最大赔率值

        # 先检测随机分配红包中有没有尾数是庄家指定要出现的尾数
        $isShow = false;
        while(!$isShow){
            $isShow = $utility->existsShowMantissa($roundRedPackets, $redEnvelopes['mantissa']);
            if(!$isShow) {
                //不存在指定的尾数就重新生成
                $roundRedPackets = $utility->redPacketRound($redEnvelopes['coin'], $redEnvelopes['need']);
            }
        }
        # 分配红包
        $user_ids = "0"; # 参与的用户UID列表

        //计算当前参与玩家的最大赔率金额
        $maxBetCoin = $redEnvelopes['coin'] * $betodds['odds'];
        //计算庄家预付的最大赔率金额
        $bankerUser_maxBetCoin = $maxBetCoin * ($redEnvelopes['need'] - 1);

        # $arr 为随机取出一个红包后的金额及删除了当前红包金额的新数组
        # 分配红包并处理帐变和门票记录
        $db->beginTrans();
        foreach ($grabUsers as $k=>$v) {
            $arr = $utility->getRedPacketFromArray($roundRedPackets);
            # 用分配到的红包金额来计算牌型 =============================================================================================
            $coin = strval($utility->formatCoin($arr['coin']));
            # 当前分配到的红包的尾数
            $current_mantissa = substr($coin, -1);   //小数点后二位

            $grabUsers[$k]['coin'] = $arr['coin'];
            $grabUsers[$k]['ticket'] = 0;
            $grabUsers[$k]['winerprofit'] = 0;

            $idsValue[$k] = array(
                'id' => $v['id'],
                'value' => array(
                    'coin' => $arr['coin'],
                    'ticket' => 0,
                    'profit' => 0,
                    'odds' => $betodds['odds'],
                    'mantissa' => $current_mantissa,
                    'winerprofit' => 0,
                    'usedtimes' => $usedtimes,
                    'state' => 1,
                )
            );

            //更新到用户抢包记录中
            $grabUsers[$k]['coin'] = $arr['coin'];
            $grabUsers[$k]['odds'] = $betodds['odds'];
            $grabUsers[$k]['mantissa'] = $current_mantissa;

            //重新组织红包数据，这个数据是删除刚刚取出那行后的新数据
            $roundRedPackets = $arr['redpackets'];

            //记录抢到的红包帐变
            $utility->setCoin(array(
                'uid' => $v['uid'],
                'gameid' => $v['gameid'],
                'coin' => $arr['coin'],
                'liqtype' => 7,
                'ex1' => $redEnvelopes['id'],
                'ex2' => $redEnvelopes['issue'],
            ));

            $user_ids .= ",".$v['uid'];
        }
        $db->commitTrans();

        //计算输赢
        # 取出庄家
        $bankerUser = $grabUsers[0];
        $othersUser = $grabUsers;

        unset($othersUser[0]);
        # 全部都跟庄家比对
        # 有四种情况
        # A：庄闲都没有打到雷 - 退回闲家和庄家的预投注
        # B：庄扫到雷有闲没有 - 闲赢 - 退回闲的预投注
        # C：庄扫到雷闲也扫到雷 - 比拿到红包的大小，红包大的赢（coin）
        # D：庄没有扫到雷闲打到了 - 庄赢
        # 庄家拿到尾数包即通赔
        $baner_back_coin = $bankerUser_maxBetCoin;
        $banker_win_total = 0;
        $banker_lost_coin = 0;
        $db->beginTrans();
        $mantissa = $redEnvelopes['mantissa'];
        foreach ($othersUser as $k=>$v) {

            # O: "默认是庄家赢，庄家没有踩雷，闲家踩雷";
            # A：庄踩雷，闲没踩雷 = 平
            # B：庄踩雷，闲也踩雷，闲抢到的金额大 = 闲赢
            # C：庄和闲都没有踩雷 = 平

            # 默认是庄闲都没有踩雷
            $follower_back_coin = $maxBetCoin;
            $follower_win_coin = 0;
            $follower_lost_coin = 0;

            # 闲家踩雷了
            /*
            if($v['mantissa'] == $mantissa){
                # 如果庄家也踩雷了但红包金额比庄家的大 - 闲赢
                if($bankerUser['mantissa']==$mantissa && $v['coin'] > $bankerUser['coin']){
                    $banker_lost_coin += $maxBetCoin;
                    $baner_back_coin -= $maxBetCoin;
                    $follower_back_coin = $maxBetCoin;
                    $follower_win_coin = $maxBetCoin;
                    $follower_lost_coin = 0;
                }else{
                    # 如果红包金额比庄家的小 - 闲输
                    $banker_win_total += $maxBetCoin;
                    $follower_back_coin = 0;
                    $follower_win_coin = (0-$maxBetCoin);
                    $follower_lost_coin = $maxBetCoin;
                }
            }else{
                # 不管庄家有没有踩雷都退还押金
                $follower_back_coin = $maxBetCoin;
                $follower_lost_coin = 0;
                $baner_back_coin = $maxBetCoin;
            }
            */
            if($v['mantissa'] == $mantissa){
                $banker_win_total += $maxBetCoin;
                $follower_back_coin = 0;
                $follower_win_coin = 0;
                $follower_lost_coin = $maxBetCoin;
                # 如果庄家也踩雷了 - 庄家赢闲输

                if($bankerUser['mantissa']==$mantissa){
                    $follower_back_coin = 0;
                    $follower_lost_coin = $maxBetCoin;
                    $baner_back_coin = $maxBetCoin;
                    $banker_win_total += $maxBetCoin;
                }else{
                    # 如果红包金额比庄家的小 - 庄赢闲输
                    $banker_win_total += $maxBetCoin;
                    //$baner_back_coin += $maxBetCoin;
                    $follower_back_coin = 0;
                    $follower_win_coin = 0;
                    $follower_lost_coin = $maxBetCoin;
                }

            }else{
                # 闲家没有踩雷，庄家踩雷
                if($bankerUser['mantissa']==$mantissa){
                    $banker_lost_coin += $maxBetCoin;
                    $baner_back_coin -= $maxBetCoin;
                    $follower_back_coin = $maxBetCoin;
                    $follower_win_coin = $maxBetCoin;
                    $follower_lost_coin = 0;
                }else{
                    $follower_back_coin = $maxBetCoin;
                    $follower_lost_coin = 0;
                    $baner_back_coin = $maxBetCoin;
                }
            }



            $follower_back_coin = $maxBetCoin;
            $follower_lost_coin = 0;

            if ($v['mantissa'] == $mantissa) {
                # 计算闲家的门票、抽水和盈亏的基数
                $follower_back_coin = 0;
                $follower_lost_coin = $maxBetCoin;
                //echo "B：庄踩雷，闲也踩雷，闲抢到的金额大 = 闲赢\n";
            }
            # 门票和抽水的计算基数
            $base_calc_coin = $v['coin'];
            if($follower_lost_coin > 0){
                if($bankerUser['mantissa'] == $mantissa && $v['coin'] > $bankerUser['coin']) {
                    $base_calc_coin = ($v['coin'] + $follower_lost_coin);
                    $banker_lost_coin += $maxBetCoin;
                }else {
                    # 如果闲家踩到了雷
                    $base_calc_coin = ($v['coin'] - $follower_lost_coin);
                    $banker_win_total += $maxBetCoin;
                }
            }else{
                # 如果庄家踩到了雷
                if($bankerUser['mantissa'] == $mantissa) {
                    $banker_lost_coin += $maxBetCoin;
                    $follower_back_coin = $maxBetCoin;
                    $follower_lost_coin = 0;
                }
            }

            # 如果是平 没有踩雷
            if ($follower_back_coin > 0) {
                # 退回闲家的预投注金币
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => floatval($follower_back_coin),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 16,
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                    )
                );
            }
            $base_calc_coin = 0;
            $ex3 = 0;
            # 如果闲家赢
            if($follower_win_coin > 0)
            {
                # 赢到红包
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => $follower_win_coin,
                        'gameid' => $game['game']['id'],
                        'liqtype' => 11, // 红包赢利
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                    )
                );
                $base_calc_coin = $follower_win_coin + $v['coin'];
                $ex3 = $base_calc_coin;
                # 计算门票
                $ticketcoin = $base_calc_coin * floatval($betodds['ticket']) / 100;
                # 计算抽水
                $winerprofitcoin = $base_calc_coin * floatval($betodds['winerprofit']) / 100;
            }else{
                $base_calc_coin = $v['coin'];
                $ex3 = $base_calc_coin;
                # 计算门票
                $ticketcoin = $base_calc_coin * floatval($betodds['ticket']) / 100;
                # 计算抽水
                $winerprofitcoin = $base_calc_coin * floatval($betodds['winerprofit']) / 100;
                # 闲家输了重置计算基数
                if($v['mantissa'] == $mantissa) {
                    # 如果闲家踩雷
                    $base_calc_coin = $v['coin'] - $maxBetCoin;
                }
            }

            # 格式化门票及抽水，只保留两位小数
            $ticketcoin = $utility->formatCoin($ticketcoin);
            $winerprofitcoin = $utility->formatCoin($winerprofitcoin);
            # 计算盈亏
            $profitcoin = $base_calc_coin - floatval($ticketcoin) - floatval($winerprofitcoin);

            if (floatval($ticketcoin) > 0) {
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => (0 - floatval($ticketcoin)),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 8, //收取的门票
                        'ex1' => $v['id'],
                        'ex2' => $v['issue'],
                        'ex3' => $ex3 . '×' . $betodds['ticket'] . '%',
                    )
                );
                $othersUser[$k]['ticket'] = $ticketcoin;
            }
            # 记闲家的抽水帐变
            if (floatval($winerprofitcoin) > 0) {
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => (0 - floatval($winerprofitcoin)),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 10, //赢到的金币要进行抽水
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                        'ex3' => $ex3 . '×' . $betodds['winerprofit'] . '%',
                    )
                );
                $othersUser[$k]['winerprofit'] = $winerprofitcoin;
            }
            $othersUser[$k]['profit'] = $profitcoin;
        }

        # 统一计算赢家的门票、抽水和盈亏
        # 返还庄家的预投注

        $baner_back_coin = $bankerUser_maxBetCoin - $banker_lost_coin;

        if($baner_back_coin > 0)
        {
            $utility->setCoin(
                array(
                    'uid' => $bankerUser['uid'],
                    'coin' => $baner_back_coin,
                    'gameid' => $game['game']['id'],
                    'liqtype' => 16,
                    'ex1' => $redEnvelopes['id'],
                    'ex2' => $redEnvelopes['issue'],
                )
            );
        }
        if($banker_win_total > 0){
            $utility->setCoin(
                array(
                    'uid' => $bankerUser['uid'],
                    'coin' => $banker_win_total,
                    'gameid' => $game['game']['id'],
                    'liqtype' => 11, // 红包赢利
                    'ex1' => $redEnvelopes['id'],
                    'ex2' => $redEnvelopes['issue'],
                )
            );
        }

        # 庄家的总共赢了多少
        $bankerUser_base_coin = floatval($banker_win_total) + floatval($bankerUser['coin']);
        $banker_ticket = $bankerUser_base_coin * floatval($betodds['ticket']) / 100;
        $banker_winprofit = $bankerUser_base_coin * floatval($betodds['winerprofit']) / 100;
        $banker_profit_coin = 0;
        if($banker_lost_coin > 0){
            $banker_profit_coin = ($banker_win_total - $banker_lost_coin) + floatval($bankerUser['coin']);
        }else{
            $banker_profit_coin = $banker_win_total + $bankerUser['coin'];
        }
        $banker_profit = $banker_profit_coin - $banker_winprofit - $banker_ticket;
        # 格式化数字
        $banker_ticket = $utility->formatCoin($banker_ticket);
        $banker_winprofit = $utility->formatCoin($banker_winprofit);
        $banker_profit = $utility->formatCoin($banker_profit);
        # 庄家的门票
        if(floatval($banker_ticket) > 0)
        {
            $utility->setCoin(
                array(
                    'uid' => $bankerUser['uid'],
                    'coin' => (0 - floatval($banker_ticket)),
                    'gameid' => $game['game']['id'],
                    'liqtype' => 8,
                    'ex1' => $v['id'],
                    'ex2' => $v['issue'],
                    'ex3' => (floatval($banker_win_total) + floatval($bankerUser['coin'])) . '×' . $betodds['ticket'] . '%',
                )
            );
            $bankerUser['ticket'] = $banker_ticket;
        }
        # 庄家的抽水
        if(floatval($banker_winprofit) > 0){
            $utility->setCoin(
                array(
                    'uid' => $bankerUser['uid'],
                    'coin' => (0 - floatval($banker_winprofit)),
                    'gameid' => $game['game']['id'],
                    'liqtype' => 10,
                    'ex1' => $v['id'],
                    'ex2' => $v['issue'],
                    'ex3' => (floatval($banker_win_total) + floatval($bankerUser['coin'])) . '×' . $betodds['winerprofit'] . '%',
                )
            );
            $bankerUser['winerprofit'] = $banker_winprofit;
        }
        $bankerUser['profit'] = $banker_profit;

        //组织前台页面展示数据
        foreach ($grabUsers as $k=>$v) {
            $profit = 0;
            //如果是庄家
            if ($v['uid'] == $bankerUser['uid']) {
                $idsValue[$k]['value']['ticket'] = $banker_ticket;
                $idsValue[$k]['value']['winerprofit'] = $banker_winprofit;
                $idsValue[$k]['value']['profit'] = $banker_profit;

                $grabUsers[$k]['ticket'] = $banker_ticket;
                $grabUsers[$k]['winerprofit'] = $banker_winprofit;
                $grabUsers[$k]['profit'] = $banker_profit;
            }else{
                //其它的就是闲家了
                foreach ($othersUser as $ok=>$ov)
                {
                    if($ov['uid'] == $grabUsers[$k]['uid']) {
                        $idsValue[$k]['value']['ticket'] = $ov['ticket'];
                        $idsValue[$k]['value']['winerprofit'] = $ov['winerprofit'];
                        $idsValue[$k]['value']['profit'] = $ov['profit'];

                        $grabUsers[$k]['ticket'] = $ov['ticket'];
                        $grabUsers[$k]['winerprofit'] = $ov['winerprofit'];
                        $grabUsers[$k]['profit'] = $ov['profit'];
                    }
                }
            }
            unset($grabUsers[$k]['issue']);
            unset($grabUsers[$k]['gameid']);
            unset($grabUsers[$k]['mantissa']);
            unset($grabUsers[$k]['odds']);
            unset($grabUsers[$k]['userid']);


            //牌型名称
            $grabUsers[$k]['cardtitle'] = '';
            //$grabUsers[$k]['times'] = $utility->formatTimes($grabUsers[$k]['times']);

        }
        //更新betslog数据库

        $update_sql = $utility->batchUpdateTable(\Config\Sys::$dbprefix.'betslog', 'id', $idsValue);
        $db->query($update_sql);
        $db->commitTrans();

        $result = array(
            'state' => 200,
            'cmd' => 'gameover',
            'datas' => array(),
            'mantissa' => $redEnvelopes['mantissa'],
            'bankercoin' => $bankerUser_maxBetCoin,
            'betcoin' => $redEnvelopes['coin'],
            'ecoin' => $game['game']['establishcoin'], //创建的红包的固定金额（固定费用）
            'ecost' => $game['game']['establishcost'], //参与游戏的费用，固定费用（包底）
            'usedtimes' => $usedtimes, //所花时间
            'needuser' => $redEnvelopes['need'],
            'grabusers' => $grabUsers,
            'times' => $utility->formatTimes($redEnvelopes['begintimes']),
            'issue' => $redEnvelopes['issue'],
            'room_name' => \Config\Sys::$gameprefix . $game['game']['id'],
            'userscoin' => $utility->sendToUidFreeCoinForIssue($grabUsers),
        );
        //结算数据推送给当期玩家
        return $result;
        //Gateway::sendToGroup($redEnvelopes['issue'], json_encode($result));
        //取出列表用户的余额数据并推送
        //$utility->sendToUidFreeCoinForIssue($grabUsers);
    }
    # endregion

    # region 3 - 扫雷
    /** 扫雷
     * @param $room_id string 房号
     * @param $game array 游戏及赔率的信息(game, odds)
     * @param $grabUsers array 参与的玩家
     * @param $redEnvelopes array 本期红包
     * @param $roundRedPackets array 分配好的红包金额
     * @param $usedtimes int 抢完本期红包所花的时间
     *
     * 庄家踩雷，免死，但发的红包金额将分配给参与的玩家
     *
     */
    private static function game_calculation_sl($room_id, $game, $grabUsers, $redEnvelopes, $roundRedPackets, $usedtimes)
    {
        global $db;
        global $redis;
        global $utility;

        $issue = $redEnvelopes['issue'];
        //取出当前玩家的赔率（按人数来区分，7人1.5倍，10人1倍）
        $betodds = $game['odds'][0]; //最大赔率值

        # 随机一个数字来识别本期是否一定要出尾数
        $randArray = array(0,0,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,0,1);
        $randArrayKey = array_rand($randArray);

        # 先检测随机分配红包中有没有尾数是庄家指定要出现的尾数
        /*
        $isShow = false;
        while($randArray[$randArrayKey]==1 && !$isShow){
            $isShow = $utility->existsShowMantissa($roundRedPackets, $redEnvelopes['mantissa']);
            if(!$isShow) {
                //不存在指定的尾数就重新生成
                $roundRedPackets = $utility->redPacketRound($redEnvelopes['coin'], $redEnvelopes['need']);
            }
        }
        */

        # 不管有没有指定的尾数都往下运行，庄家免死（2018-05-05）

        # 分配红包
        $user_ids = "0"; # 参与的用户UID列表

        //计算当前参与玩家的最大赔率金额
        $maxBetCoin = $redEnvelopes['coin'] * $betodds['odds'];
        // 有倍数的情况下：计算庄家预付的最大赔率金额
        //$bankerUser_maxBetCoin = $maxBetCoin * ($redEnvelopes['need'] - 1);
        // 新玩法说明：庄家的最大暂扣金额无需加倍 直接就是扣除红包的金额
        $bankerUser_maxBetCoin = $redEnvelopes['coin'];// $maxBetCoin * ($redEnvelopes['need'] - 1);

        # 检测有几个玩家是机器人，如果全是机器人，按红包的金额来确定是否主动分配红包，默认是随机分配

        # $arr 为随机取出一个红包后的金额及删除了当前红包金额的新数组
        # 分配红包并处理帐变和门票记录
        $db->beginTrans();
        //var_dump($grabUsers);
        $grabUsersLen = count($grabUsers) - 1;
        for($k=$grabUsersLen; $k>=0; $k--){
            $v = $grabUsers[$k];
        //foreach ($grabUsers as $k=>$v) {
            $args = array(
                'mantissa' => $redEnvelopes['mantissa'],
                'uid' => $v['uid'],
                'gameid' => $redEnvelopes['gameid'],
                'usertype' => $redEnvelopes['usertype'],
                'odds' => $game['odds'],
            );
            $arr = $utility->getRedPacketFromArray($roundRedPackets, $args);
            # 用分配到的红包金额来计算牌型 =============================================================================================
            $coin = strval($utility->formatCoin($arr['coin']));
            # 当前分配到的红包的尾数
            $current_mantissa = substr($coin, -1);   //小数点后二位

            $grabUsers[$k]['coin'] = $arr['coin'];
            $grabUsers[$k]['ticket'] = 0;
            $grabUsers[$k]['winerprofit'] = 0;

            $idsValue[$k] = array(
                'id' => $v['id'],
                'value' => array(
                    'coin' => $arr['coin'],
                    'ticket' => 0,
                    'profit' => 0,
                    'odds' => $betodds['odds'],
                    'mantissa' => $current_mantissa,
                    'winerprofit' => 0,
                    'usedtimes' => $usedtimes,
                    'state' => 1,
                )
            );

            //更新到用户抢包记录中
            $grabUsers[$k]['coin'] = $arr['coin'];
            $grabUsers[$k]['odds'] = $betodds['odds'];
            $grabUsers[$k]['mantissa'] = $current_mantissa;

            //重新组织红包数据，这个数据是删除刚刚取出那行后的新数据
            $roundRedPackets = $arr['redpackets'];

            //记录抢到的红包帐变
            $utility->setCoin(array(
                'uid' => $v['uid'],
                'gameid' => $v['gameid'],
                'coin' => $arr['coin'],
                'liqtype' => 7,
                'ex1' => $redEnvelopes['id'],
                'ex2' => $redEnvelopes['issue'],
            ));

            $user_ids .= ",".$v['uid'];
        }
        $db->commitTrans();

        //计算输赢
        # 取出庄家
        $bankerUser = $grabUsers[0];
        $othersUser = $grabUsers;

        unset($othersUser[0]);
        # 全部都跟庄家比对
        # 有四种情况
        # A：庄闲都没有打到雷 - 退回闲家和庄家的预投注, 庄家的红包大家平分
        # B：庄扫到雷有闲没有 - 闲赢 - 庄免死，闲家获取红包，退回闲的预投注
        # C：庄扫到雷闲也扫到雷 - 庄赢，闲家得红包，扣除倍数金额
        # D：庄没有扫到雷闲打到了 - 庄赢
        # 庄家拿到尾数包即免死 - 发放的红包即直接分配
        $baner_back_coin = $bankerUser_maxBetCoin;
        $banker_win_total = 0;
        $banker_lost_coin = 0;
        $db->beginTrans();
        $mantissa = $redEnvelopes['mantissa'];
        foreach ($othersUser as $k=>$v) {
            # O: "默认是庄家赢，庄家没有踩雷，闲家踩雷";
            # A：庄踩雷，闲没踩雷 = 庄免死，闲分红包
            # B：庄踩雷，闲也踩雷，闲抢到的金额大 = 闲赢
            # C：庄和闲都没有踩雷 = 平，分红包

            # 默认是庄闲都没有踩雷
            $follower_back_coin = $maxBetCoin;
            $follower_win_coin = 0;
            $follower_lost_coin = 0;

            # 闲家踩雷了
            if($v['mantissa'] == $mantissa){
                $banker_win_total += $maxBetCoin;
                $follower_back_coin = 0;
                $follower_win_coin = 0;
                $follower_lost_coin = $maxBetCoin;
            }else{
                # 闲家没有踩雷
                $follower_back_coin = $maxBetCoin;
                $follower_lost_coin = 0;
                $baner_back_coin = $maxBetCoin;
            }
            /*


            $follower_back_coin = $maxBetCoin;
            $follower_lost_coin = 0;

            if ($v['mantissa'] == $mantissa) {
                # 计算闲家的门票、抽水和盈亏的基数
                $follower_back_coin = 0;
                $follower_lost_coin = $maxBetCoin;
                //echo "B：庄踩雷，闲也踩雷，闲抢到的金额大 = 闲赢\n";
            }
            # 门票和抽水的计算基数
            $base_calc_coin = $v['coin'];
            if($follower_lost_coin > 0){
                if($bankerUser['mantissa'] == $mantissa && $v['coin'] > $bankerUser['coin']) {
                    $base_calc_coin = ($v['coin'] + $follower_lost_coin);
                    $banker_lost_coin += $maxBetCoin;
                }else {
                    # 如果闲家踩到了雷
                    $base_calc_coin = ($v['coin'] - $follower_lost_coin);
                    $banker_win_total += $maxBetCoin;
                }
            }else{
                # 如果庄家踩到了雷
                if($bankerUser['mantissa'] == $mantissa) {
                    $banker_lost_coin += $maxBetCoin;
                    $follower_back_coin = $maxBetCoin;
                    $follower_lost_coin = 0;
                }
            }
            */
            # 如果是平 没有踩雷
            if ($follower_back_coin > 0) {
                # 退回闲家的预投注金币
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => floatval($follower_back_coin),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 16,
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                    )
                );
            }
            $base_calc_coin = 0;
            $ex3 = 0;
            # 如果闲家赢
            if($follower_win_coin > 0)
            {
                # 赢到红包
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => $follower_win_coin,
                        'gameid' => $game['game']['id'],
                        'liqtype' => 11, // 红包赢利
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                    )
                );
                $base_calc_coin = $follower_win_coin + $v['coin'];
                $ex3 = $base_calc_coin;
                # 计算门票
                $ticketcoin = $base_calc_coin * floatval($betodds['ticket']) / 100;
                # 计算抽水
                $winerprofitcoin = $base_calc_coin * floatval($betodds['winerprofit']) / 100;
            }else{
                $base_calc_coin = $v['coin'];
                $ex3 = $base_calc_coin;
                # 计算门票
                $ticketcoin = $base_calc_coin * floatval($betodds['ticket']) / 100;
                # 计算抽水
                $winerprofitcoin = $base_calc_coin * floatval($betodds['winerprofit']) / 100;
                # 闲家输了重置计算基数
                if($v['mantissa'] == $mantissa) {
                    # 如果闲家踩雷
                    $base_calc_coin = $v['coin'] - $maxBetCoin;
                }
            }

            # 格式化门票及抽水，只保留两位小数
            $ticketcoin = $utility->formatCoin($ticketcoin);
            $winerprofitcoin = $utility->formatCoin($winerprofitcoin);
            # 计算盈亏
            $profitcoin = $base_calc_coin - floatval($ticketcoin) - floatval($winerprofitcoin);

            if (floatval($ticketcoin) > 0) {
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => (0 - floatval($ticketcoin)),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 8, //收取的门票
                        'ex1' => $v['id'],
                        'ex2' => $v['issue'],
                        'ex3' => $ex3 . '×' . $betodds['ticket'] . '%',
                    )
                );
                $othersUser[$k]['ticket'] = $ticketcoin;
            }
            # 记闲家的抽水帐变
            if (floatval($winerprofitcoin) > 0) {
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => (0 - floatval($winerprofitcoin)),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 10, //赢到的金币要进行抽水
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                        'ex3' => $ex3 . '×' . $betodds['winerprofit'] . '%',
                    )
                );
                $othersUser[$k]['winerprofit'] = $winerprofitcoin;
            }
            $othersUser[$k]['profit'] = $profitcoin;
        }

        # 统一计算赢家的门票、抽水和盈亏

        if($banker_win_total > 0){
            $utility->setCoin(
                array(
                    'uid' => $bankerUser['uid'],
                    'coin' => $banker_win_total,
                    'gameid' => $game['game']['id'],
                    'liqtype' => 11, // 红包赢利
                    'ex1' => $redEnvelopes['id'],
                    'ex2' => $redEnvelopes['issue'],
                )
            );
        }

        # 庄家的总共赢了多少
        $bankerUser_base_coin = floatval($banker_win_total) + floatval($bankerUser['coin']);
        $banker_ticket = $bankerUser_base_coin * floatval($betodds['ticket']) / 100;
        $banker_winprofit = $bankerUser_base_coin * floatval($betodds['winerprofit']) / 100;
        $banker_profit_coin = 0;
        if($banker_lost_coin > 0){
            $banker_profit_coin = ($banker_win_total - $banker_lost_coin) + floatval($bankerUser['coin']);
        }else{
            $banker_profit_coin = $banker_win_total + $bankerUser['coin'];
        }
        # 2018-05-05 要扣除红包的金额，红包的金额($redEnvelopes['coin'])是一定要分配给参与玩家的
        $banker_profit = $banker_profit_coin - $banker_winprofit - $banker_ticket - $redEnvelopes['coin'];
        # 格式化数字
        $banker_ticket = $utility->formatCoin($banker_ticket);
        $banker_winprofit = $utility->formatCoin($banker_winprofit);
        $banker_profit = $utility->formatCoin($banker_profit);
        # 庄家的门票
        if(floatval($banker_ticket) > 0)
        {
            $utility->setCoin(
                array(
                    'uid' => $bankerUser['uid'],
                    'coin' => (0 - floatval($banker_ticket)),
                    'gameid' => $game['game']['id'],
                    'liqtype' => 8,
                    'ex1' => $v['id'],
                    'ex2' => $v['issue'],
                    'ex3' => (floatval($banker_win_total) + floatval($bankerUser['coin'])) . '×' . $betodds['ticket'] . '%',
                )
            );
            $bankerUser['ticket'] = $banker_ticket;
        }
        # 庄家的抽水
        if(floatval($banker_winprofit) > 0){
            $utility->setCoin(
                array(
                    'uid' => $bankerUser['uid'],
                    'coin' => (0 - floatval($banker_winprofit)),
                    'gameid' => $game['game']['id'],
                    'liqtype' => 10,
                    'ex1' => $v['id'],
                    'ex2' => $v['issue'],
                    'ex3' => (floatval($banker_win_total) + floatval($bankerUser['coin'])) . '×' . $betodds['winerprofit'] . '%',
                )
            );
            $bankerUser['winerprofit'] = $banker_winprofit;
        }
        $bankerUser['profit'] = $banker_profit;

        //组织前台页面展示数据
        foreach ($grabUsers as $k=>$v) {
            $profit = 0;
            //如果是庄家
            if ($v['uid'] == $bankerUser['uid']) {
                $idsValue[$k]['value']['ticket'] = $banker_ticket;
                $idsValue[$k]['value']['winerprofit'] = $banker_winprofit;
                $idsValue[$k]['value']['profit'] = $banker_profit;

                $grabUsers[$k]['ticket'] = $banker_ticket;
                $grabUsers[$k]['winerprofit'] = $banker_winprofit;
                $grabUsers[$k]['profit'] = $banker_profit;
            }else{
                //其它的就是闲家了
                foreach ($othersUser as $ok=>$ov)
                {
                    if($ov['uid'] == $grabUsers[$k]['uid']) {
                        $idsValue[$k]['value']['ticket'] = $ov['ticket'];
                        $idsValue[$k]['value']['winerprofit'] = $ov['winerprofit'];
                        $idsValue[$k]['value']['profit'] = $ov['profit'];

                        $grabUsers[$k]['ticket'] = $ov['ticket'];
                        $grabUsers[$k]['winerprofit'] = $ov['winerprofit'];
                        $grabUsers[$k]['profit'] = $ov['profit'];
                    }
                }
            }
            unset($grabUsers[$k]['issue']);
            unset($grabUsers[$k]['gameid']);
            unset($grabUsers[$k]['mantissa']);
            unset($grabUsers[$k]['odds']);
            unset($grabUsers[$k]['userid']);


            //牌型名称
            $grabUsers[$k]['cardtitle'] = '';
            //$grabUsers[$k]['times'] = $utility->formatTimes($grabUsers[$k]['times']);

        }
        //更新betslog数据库

        $update_sql = $utility->batchUpdateTable(\Config\Sys::$dbprefix.'betslog', 'id', $idsValue);
        $db->query($update_sql);
        $db->commitTrans();

        $result = array(
            'state' => 200,
            'cmd' => 'gameover',
            'datas' => array(),
            'mantissa' => $redEnvelopes['mantissa'],
            'bankercoin' => $bankerUser_maxBetCoin,
            'betcoin' => $redEnvelopes['coin'],
            'ecoin' => $game['game']['establishcoin'], //创建的红包的固定金额（固定费用）
            'ecost' => $game['game']['establishcost'], //参与游戏的费用，固定费用（包底）
            'usedtimes' => $usedtimes, //所花时间
            'needuser' => $redEnvelopes['need'],
            'grabusers' => $grabUsers,
            'times' => $utility->formatTimes($redEnvelopes['begintimes']),
            'issue' => $redEnvelopes['issue'],
            'room_name' => \Config\Sys::$gameprefix . $game['game']['id'],
            'userscoin' => $utility->sendToUidFreeCoinForIssue($grabUsers),
        );
        //结算数据推送给当期玩家
        return $result;
        //Gateway::sendToGroup($redEnvelopes['issue'], json_encode($result));
        //取出列表用户的余额数据并推送
        //$utility->sendToUidFreeCoinForIssue($grabUsers);
    }
    # endregion

    # region 4 - 二八杠
    /** 二八杠
     * @param $room_id string 房号
     * @param $game array 游戏及赔率的信息(game, odds)
     * @param $grabUsers array 参与的玩家
     * @param $redEnvelopes array 本期红包
     * @param $roundRedPackets array 分配好的红包金额
     * @param $usedtimes int 抢完本期红包所花的时间
     */
    private static function game_calculation_ebg($room_id, $game, $grabUsers, $redEnvelopes, $roundRedPackets, $usedtimes)
    {
        global $db;
        global $redis;
        global $utility;

        # 分配红包
        $user_ids = "0"; # 参与的用户UID列表
        $ticket = isset($game['odds'][0]['ticket']) ? $game['odds'][0]['ticket'] : 3;
        //找出庄家 - 第一个，最早参与的就是庄家
        //$bankerUser = $grabUsers[0];
        //计算当前参与玩家的最大赔率金额
        $maxBetCoin = $redEnvelopes['coin'] * $game['odds'][0]['odds'];
        //计算庄家预付的最大赔率金额
        $bankerUser_maxBetCoin = $maxBetCoin * ($redEnvelopes['need'] - 1);

        //庄家赢的总金额(以备收门票和抽水),闲家赢的每玩家分次收取
        $bankerUser_win_coin_total = 0;
        $bankerUser_los_coin_total = 0;
        /*
         * 牛牛：后面两位数相加 = 0
         * 对子：后面两位数相同
         * 牛几：后面两位数不是对子也不是牛牛，即比点数大小了
         */
        $grabUsersLen = count($grabUsers) - 1;
        for($k=$grabUsersLen; $k>=0; $k--){
            $v = $grabUsers[$k];
            //foreach ($grabUsers as $k=>$v)
            //{
            $args = array(
                'mantissa' => $redEnvelopes['mantissa'],
                'uid' => $v['uid'],
                'gameid' => $redEnvelopes['gameid'],
                'usertype' => $redEnvelopes['usertype'],
                'odds' => $game['odds'],
            );
            $arr = $utility->getRedPacketFromArray($roundRedPackets, $args);
            # 用分配到的红包金额来计算牌型 =============================================================================================
            $coin = strval(number_format($arr['coin'], 2, '.', ''));

            $n1 = substr($coin,-2,1); //小数点第一位
            $n2 = substr($coin,-1);   //小数点后二位

            # region 匹配设置好的红包牌型
            $n1n2 = $n1 . $n2;

            $cardtype_number = (($n1+$n2) % 10);
            $winsort_odds_key = 'd0'; // 0点

            # 白板+X点
            if($n1=='0'){
                $winsort_odds_key = 'b0d' . $n2;
            }else{
                # 点数
                if(($n1+$n2) > 0){
                    $winsort_odds_key = 'd' . $cardtype_number;
                }
            }
            # 二八杠
            if($n1n2=='28'){
                $winsort_odds_key = 'ebg28';
            }
            # 对子
            if($n1 == $n2){
                $winsort_odds_key = 'dz' . $n1;
            }
            # 对白板
            if($n1n2=='00'){
                $winsort_odds_key = 'd00';
            }
            # endregion

            # ======================================================================================================
            //找出对应输赢的牌型顺序
            $grabUsers[$k]['winsort'] = $utility->getOddsWinSort($game['odds'],'cardtype', $winsort_odds_key, 'winsort');
            //找出对应的赔率
            $grabUsers[$k]['odds'] = $utility->getOddsWinSort($game['odds'],'cardtype', $winsort_odds_key, 'odds');
            //牌型名称
            $grabUsers[$k]['cardtitle'] = $utility->getOddsWinSort($game['odds'],'cardtype', $winsort_odds_key, 'cardtitle');
            //计算门票
            //$ticketcoin = $utility->formatCoin(($redEnvelopes['coin'] * $grabUsers[$k]['odds'] * $ticket) / 100);

            //更新到用户抢包记录中
            $grabUsers[$k]['coin'] = $arr['coin'];
            $grabUsers[$k]['ticket'] = 0;
            $grabUsers[$k]['winerprofit'] = 0;
            $grabUsers[$k]['cardtype'] = $winsort_odds_key;

            $idsValue[$k] = array(
                'id' => $v['id'],
                'value' => array(
                    'coin' => $arr['coin'],
                    'ticket' => 0,
                    'profit' => 0,
                    'odds' => $grabUsers[$k]['odds'],
                    'cardtype' => $winsort_odds_key,
                    'winsort' => $grabUsers[$k]['winsort'],
                    'winerprofit' => 0,
                    'usedtimes' => $usedtimes,
                    'state' => 1,
                )
            );

            $user_ids .= ",".$v['uid'];

            $roundRedPackets = $arr['redpackets'];
        }
        //找出庄家 - 第一个，最早参与的就是庄家
        $bankerUser = $grabUsers[0];
        //找出闲家(第一个是庄家，其它的都是跟抢的闲家)
        $otherUsers = $grabUsers;
        unset($otherUsers[0]);

        //找出庄家后开始与其它玩家进行对比
        $db->beginTrans();
        foreach ($grabUsers as $k=>$v)
        {
            # 记录抢到的红包
            $utility->setCoin(
                array(
                    'uid' => $v['uid'],
                    'coin' => floatval($v['coin']),
                    'gameid' => $game['game']['id'],
                    'liqtype' => 7,
                    'ex1' => $redEnvelopes['id'],
                    'ex2' => $redEnvelopes['issue'],
                )
            );
        }
        foreach($otherUsers as $k=>$v)
        {
            //默认是庄家赢
            $winer = array(
                'uid' => $bankerUser['uid'],
                'cardtype' => $bankerUser['cardtype'],
                'wincoin' => ($redEnvelopes['coin'] * $bankerUser['odds']), //默认按最大赔率支付
            );
            //庄家赢的标志
            $banker_win = true;
            //比牌型,winsort的值,如果winsort的值一样，即比进入的时间
            if($v['winsort']==$bankerUser['winsort'])
            {
                //如果两个人的牌型一样,即比拿到的金额大小
                if($v['coin'] > $bankerUser['coin']){
                    $winer['uid'] = $v['uid'];
                    $banker_win = false;
                }
            }else{
                //如果闲家的牌型比庄家的好
                if($v['winsort'] > $bankerUser['winsort'])
                {
                    $winer['uid'] = $v['uid'];
                    $banker_win = false;
                }
            }
            if($banker_win)
            {
                //庄家赢
                //庄家要收取的金币 = （用户的预投注金额 - （投注本额 * 赢家的最终赔率））
                //闲家要收回的金币 = 玩家的预投注金额 - 庄家收取的金币额
                $banker_win_coin = $redEnvelopes['coin'] * $bankerUser['odds'];
                $bankerUser_win_coin_total += $banker_win_coin;
                //记录赢到的金币帐变
                $utility->setCoin(
                    array(
                        'uid' => $winer['uid'],
                        'coin' => floatval($banker_win_coin),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 11,
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                    )
                );

                //如果庄家的赔率不是最大倍率，还要将余下的金币退回给参与玩家
                if($maxBetCoin - $banker_win_coin > 0 ){
                    $utility->setCoin(
                        array(
                            'uid' => $v['uid'],
                            'coin' => floatval($maxBetCoin - $banker_win_coin),
                            'gameid' => $game['game']['id'],
                            'liqtype' => 16,
                            'ex1' => $redEnvelopes['id'],
                            'ex2' => $redEnvelopes['issue'],
                        )
                    );
                }

                //赢家统一在后面($bankerUser_win_coin_total)计算抽水
                //$winerprofit_coin = $game['game'][0]['winerprofit']  * $banker_win_coin;
            }else{
                //退回闲家的预投注金额
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => floatval($maxBetCoin),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 9, //赢家，退回对应预投注的红包
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                    )
                );
                //按赔率计算赢到的金额
                $user_win_coin = $redEnvelopes['coin'] * $v['odds'];
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => floatval($user_win_coin),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 11, //赢到的金币
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                    )
                );
                //交门票
                //闲家赢 - 门票
                $ticketcoin = $utility->formatCoin((($user_win_coin + $v['coin']) * $ticket) / 100);
                if($ticketcoin > 0) {
                    $utility->setCoin(
                        array(
                            'uid' => $v['uid'],
                            'coin' => (0 - floatval($ticketcoin)),
                            'gameid' => $game['game']['id'],
                            'liqtype' => 8, //赢到的金币要交门票
                            'ex1' => $redEnvelopes['id'],
                            'ex2' => $redEnvelopes['issue'],
                            'ex3' => ($user_win_coin + $v['coin']) . '×' . $ticket .'%',
                        )
                    );
                }
                $otherUsers[$k]['ticket'] =  $ticketcoin;

                //赢家抽水
                $winerprofit = $utility->formatCoin((($user_win_coin + $v['coin']) * $game['odds'][0]['winerprofit']) / 100);
                if($winerprofit > 0) {
                    $utility->setCoin(
                        array(
                            'uid' => $v['uid'],
                            'coin' => (0 - floatval($winerprofit)),
                            'gameid' => $game['game']['id'],
                            'liqtype' => 10, //赢到的金币要进行抽水
                            'ex1' => $redEnvelopes['id'],
                            'ex2' => $redEnvelopes['issue'],
                            'ex3' => ($user_win_coin + $v['coin']) . '×' . $game['odds'][0]['winerprofit'].'%',
                        )
                    );
                }
                $otherUsers[$k]['winerprofit'] =  $winerprofit;

                $bankerUser_los_coin_total += $user_win_coin;
            }
        }
        $db->commitTrans();

        //庄家赢利门票及抽水及把余下的预投注还给庄家
        $bankerUser_win_ticket = 0;
        $bankerUser_win_profit = 0;

        $db->beginTrans();
        if($bankerUser_win_coin_total > 0)
        {
            //门票
            $bankerUser_win_ticket = (($bankerUser_win_coin_total + $bankerUser['coin']) *  floatval($game['odds'][0]['ticket'])) / 100;
            $bankerUser_win_ticket = $utility->formatCoin($bankerUser_win_ticket);
            if($bankerUser_win_ticket > 0) {
                $utility->setCoin(
                    array(
                        'uid' => $bankerUser['uid'],
                        'coin' => (0 - floatval($bankerUser_win_ticket)),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 8, //赢到的金币要交门票
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                        'ex3' => ($bankerUser_win_coin_total + $bankerUser['coin']) . '×' . $ticket .'%',
                    )
                );
            }
            $bankerUser['ticket'] = $bankerUser_win_ticket;
            //抽水
            $bankerUser_win_profit = (($bankerUser_win_coin_total + $bankerUser['coin']) *  floatval($game['odds'][0]['winerprofit'])) / 100;
            $bankerUser_win_profit = $utility->formatCoin($bankerUser_win_profit);
            if($bankerUser_win_profit > 0) {
                $utility->setCoin(
                    array(
                        'uid' => $bankerUser['uid'],
                        'coin' => (0 - floatval($bankerUser_win_profit)),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 10, //赢到的金币抽水
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                        'ex3' => ($bankerUser_win_coin_total + $bankerUser['coin']) . '×' . $game['odds'][0]['winerprofit'] .'%',
                    )
                );
            }
            $bankerUser['winerprofit'] = $bankerUser_win_profit;
            $bankerUser['ticket'] = $bankerUser_win_ticket;
        }
        //把余款还给庄家
        $back_bankerUser_coin = $bankerUser_maxBetCoin - $bankerUser_los_coin_total;
        if($back_bankerUser_coin > 0){
            $utility->setCoin(
                array(
                    'uid' => $bankerUser['uid'],
                    'coin' => floatval($back_bankerUser_coin),
                    'gameid' => $game['game']['id'],
                    'liqtype' => 16, //庄家还有预投注的余额，退回
                    'ex1' => $redEnvelopes['id'],
                    'ex2' => $redEnvelopes['issue'],
                )
            );
        }
        # 更新betslog的记录
        foreach ($grabUsers as $k=>$v)
        {
            $profit = 0;
            $ticket = 0;
            //如果是庄家
            if($v['uid']==$bankerUser['uid'])
            {
                $idsValue[$k]['value']['ticket'] = $bankerUser_win_ticket;
                $idsValue[$k]['value']['winerprofit'] = $bankerUser_win_profit;
                $grabUsers[$k]['ticket'] = $bankerUser_win_ticket;
                $grabUsers[$k]['winerprofit'] = $bankerUser_win_profit;

                $betNeedCoin = $game['game']['establishcoin'];

                if ($game['game']['ishavebanker']) {
                    //庄家的预计赔注（(人数 -1) * 红包的基本投注 * 最大赔率)）
                    //找出游戏的最大赔率( 游戏的赔率是按从大到小的来排序，所以最上面一个就是最大的赔率，后台设置时需要把牌型最大的winsort值最为最大)
                    $maxodds = $game['odds'][0]['odds'];
                    $betNeedCoin = (($redEnvelopes['need'] - 1) * $redEnvelopes['coin'] * $maxodds);
                }
                $profit = $bankerUser_win_coin_total - $bankerUser_los_coin_total + $v['coin'] - $grabUsers[$k]['ticket'] - $grabUsers[$k]['winerprofit'];

                $grabUsers[$k]['issue_usertype'] = 1;
            }else{
                //其它的就是闲家了
                foreach ($otherUsers as $ok=>$ov)
                {
                    if($v['uid']==$ov['uid'])
                    {
                        $idsValue[$k]['value']['ticket'] = $otherUsers[$ok]['ticket'];
                        $idsValue[$k]['value']['winerprofit'] = $otherUsers[$ok]['winerprofit'];
                        $grabUsers[$k]['ticket'] = $otherUsers[$ok]['ticket'];
                        $grabUsers[$k]['winerprofit'] = $otherUsers[$ok]['winerprofit'];

                        //如果庄家赢
                        if($v['winsort'] < $bankerUser['winsort'])
                        {
                            //按庄家的赔率来计算(最大预投注 - 赔给庄家的金币 - 门票 - 抽水)
                            $profit = $v['coin'] - ($bankerUser['odds'] * $redEnvelopes['coin']) - $otherUsers[$ok]['ticket'] - $otherUsers[$ok]['winerprofit'];
                        }
                        //闲家赢
                        if($v['winsort'] > $bankerUser['winsort']){
                            //按闲家的赔率来计算(最大预投注 - 赔给庄家的金币 - 门票 - 抽水)
                            $profit = ($otherUsers[$ok]['odds'] * $redEnvelopes['coin']) + $otherUsers[$ok]['coin'] - $otherUsers[$ok]['ticket'] - $otherUsers[$ok]['winerprofit'];
                        }
                        //如果winsort相同，对比金额 - 大 - 赢
                        if($v['winsort'] == $bankerUser['winsort'] && $v['coin'] > $bankerUser['coin'])
                        {
                            $profit = ($otherUsers[$ok]['odds'] * $redEnvelopes['coin']) + $otherUsers[$ok]['coin'] - $otherUsers[$ok]['ticket'] - $otherUsers[$ok]['winerprofit'];
                        }
                        //如果winsort相同，对比金额 - 小 - 输
                        if($v['winsort'] == $bankerUser['winsort'] && $v['coin'] <= $bankerUser['coin'])
                        {
                            $profit = $v['coin'] - ($bankerUser['odds'] * $redEnvelopes['coin']) - $otherUsers[$ok]['ticket'] - $otherUsers[$ok]['winerprofit'];
                        }
                        $grabUsers[$k]['issue_usertype'] = 0;
                    }
                }
            }
            //最终盈利
            $grabUsers[$k]['profit'] = $utility->formatCoin($profit);
            $idsValue[$k]['value']['ticket'] = $grabUsers[$k]['ticket'];
            $idsValue[$k]['value']['profit'] = $grabUsers[$k]['profit'];
            #  格式化日期
            //$grabUsers[$k]['times'] = $utility->formatTimes($grabUsers[$k]['times']);
            unset($grabUsers[$k]['issue']);
            unset($grabUsers[$k]['gameid']);
            unset($grabUsers[$k]['mantissa']);
            unset($grabUsers[$k]['odds']);
            unset($grabUsers[$k]['userid']);
            unset($grabUsers[$k]['mantissa']);
        }
        //更新betslog数据库
        $update_sql = $utility->batchUpdateTable(\Config\Sys::$dbprefix.'betslog', 'id', $idsValue);
        $db->query($update_sql);
        $db->commitTrans();
        #endregion

        $result = array(
            'state' => 200,
            'cmd' => 'gameover',
            'datas' => array(),
            'mantissa' => '',
            'bankercoin' => $betNeedCoin,
            'betcoin' => $redEnvelopes['coin'],
            'ecoin' => $game['game']['establishcoin'], //创建的红包的固定金额（固定费用）
            'ecost' => $game['game']['establishcost'], //参与游戏的费用，固定费用（包底）
            'usedtimes' => $usedtimes, //所花时间
            'needuser' => $redEnvelopes['need'],
            'grabusers' => $grabUsers,
            'times' => $utility->formatTimes($redEnvelopes['begintimes']),
            'issue' => $redEnvelopes['issue'],
            'room_name' => \Config\Sys::$gameprefix . $game['game']['id'],
            'userscoin' => $utility->sendToUidFreeCoinForIssue($grabUsers),
        );
        return $result;
        //Gateway::sendToGroup($redEnvelopes['issue'], json_encode($result));
        //取出列表用户的余额数据并推送
        //$utility->sendToUidFreeCoinForIssue($grabUsers);
        //结算数据推送给当期玩家
    }
    # endregion

    # region 5 - 十倍牛

    /** 十倍牛
     * @param $room_id string 房号
     * @param $game array 游戏及赔率的信息(game, odds)
     * @param $grabUsers array 参与的玩家
     * @param $redEnvelopes array 本期红包
     * @param $roundRedPackets array 分配好的红包金额
     * @param $usedtimes int 抢完本期红包所花的时间
     */
    private static function game_calculation_sbn($room_id, $game, $grabUsers, $redEnvelopes, $roundRedPackets, $usedtimes)
    {
        global $db;
        global $redis;
        global $utility;

        # 分配红包
        $user_ids = "0"; # 参与的用户UID列表
        $ticket = isset($game['odds'][0]['ticket']) ? $game['odds'][0]['ticket'] : 3;
        //找出庄家 - 第一个，最早参与的就是庄家
        //$bankerUser = $grabUsers[0];
        //计算当前参与玩家的最大赔率金额
        $maxBetCoin = $redEnvelopes['coin'] * $game['odds'][0]['odds'];
        //计算庄家预付的最大赔率金额
        $bankerUser_maxBetCoin = $maxBetCoin * ($redEnvelopes['need'] - 1);

        //庄家赢的总金额(以备收门票和抽水),闲家赢的每玩家分次收取
        $bankerUser_win_coin_total = 0;
        $bankerUser_los_coin_total = 0;
        /*
         * 牛牛：后面两位数相加 = 0
         * 对子：后面两位数相同
         * 牛几：后面两位数不是对子也不是牛牛，即比点数大小了
         */

        $grabUsersLen = count($grabUsers) - 1;
        for($k=$grabUsersLen; $k>=0; $k--){
            $v = $grabUsers[$k];
            //foreach ($grabUsers as $k=>$v)
            //{
            $args = array(
                'mantissa' => $redEnvelopes['mantissa'],
                'uid' => $v['uid'],
                'gameid' => $redEnvelopes['gameid'],
                'usertype' => $redEnvelopes['usertype'],
                'odds' => $game['odds'],
            );
            $arr = $utility->getRedPacketFromArray($roundRedPackets, $args);
            # 用分配到的红包金额来计算牌型 =============================================================================================
            $coin = strval(number_format($arr['coin'], 2, '.', ''));
            $n1 = substr($coin,-2,1); //小数点第一位
            $n2 = substr($coin,-1);   //小数点后二位

            $winsort_odds_key = 'n'.(($n1+$n2) % 10); // 牛几

            // 最后是最大的牌型：牛牛
            if((($n1+$n2) % 10)==0){
                $winsort_odds_key = "n0";
            }
            # ======================================================================================================
            //找出对应输赢的牌型顺序
            $grabUsers[$k]['winsort'] = $utility->getOddsWinSort($game['odds'],'cardtype', $winsort_odds_key, 'winsort');
            //找出对应的赔率
            $grabUsers[$k]['odds'] = $utility->getOddsWinSort($game['odds'],'cardtype', $winsort_odds_key, 'odds');
            //牌型名称
            $grabUsers[$k]['cardtitle'] = $utility->getOddsWinSort($game['odds'],'cardtype', $winsort_odds_key, 'cardtitle');
            //计算门票
            //$ticketcoin = $utility->formatCoin(($redEnvelopes['coin'] * $grabUsers[$k]['odds'] * $ticket) / 100);

            //更新到用户抢包记录中
            $grabUsers[$k]['coin'] = $arr['coin'];
            $grabUsers[$k]['ticket'] = 0;
            $grabUsers[$k]['winerprofit'] = 0;
            $grabUsers[$k]['cardtype'] = $winsort_odds_key;

            $idsValue[$k] = array(
                'id' => $v['id'],
                'value' => array(
                    'coin' => $arr['coin'],
                    'ticket' => 0,
                    'profit' => 0,
                    'odds' => $grabUsers[$k]['odds'],
                    'cardtype' => $winsort_odds_key,
                    'winsort' => $grabUsers[$k]['winsort'],
                    'winerprofit' => 0,
                    'usedtimes' => $usedtimes,
                    'state' => 1,
                )
            );


            $user_ids .= ",".$v['uid'];

            $roundRedPackets = $arr['redpackets'];

            # 记录抢到的红包
            $utility->setCoin(
                array(
                    'uid' => $v['uid'],
                    'coin' => floatval($arr['coin']),
                    'gameid' => $game['game']['id'],
                    'liqtype' => 7,
                    'ex1' => $redEnvelopes['id'],
                    'ex2' => $redEnvelopes['issue'],
                )
            );

        }
        //找出庄家 - 第一个，最早参与的就是庄家
        $bankerUser = $grabUsers[0];
        //找出闲家(第一个是庄家，其它的都是跟抢的闲家)
        $otherUsers = $grabUsers;
        unset($otherUsers[0]);

        //找出庄家后开始与其它玩家进行对比
        $db->beginTrans();
        foreach($otherUsers as $k=>$v)
        {
            //默认是庄家赢
            $winer = array(
                'uid' => $bankerUser['uid'],
                'cardtype' => $bankerUser['cardtype'],
                'wincoin' => ($redEnvelopes['coin'] * $bankerUser['odds']), //默认按最大赔率支付
            );
            //庄家赢的标志
            $banker_win = true;
            //比牌型,winsort的值,如果winsort的值一样，即比进入的时间
            if($v['winsort']==$bankerUser['winsort'])
            {
                //如果两个人的牌型一样,即比拿到的金额大小
                if($v['coin'] > $bankerUser['coin']){
                    $winer['uid'] = $v['uid'];
                    $banker_win = false;
                }
            }else{
                //如果闲家的牌型比庄家的好
                if($v['winsort'] > $bankerUser['winsort'])
                {
                    $winer['uid'] = $v['uid'];
                    $banker_win = false;
                }
            }
            if($banker_win)
            {
                //庄家赢
                //庄家要收取的金币 = （用户的预投注金额 - （投注本额 * 赢家的最终赔率））
                //闲家要收回的金币 = 玩家的预投注金额 - 庄家收取的金币额
                $banker_win_coin = $redEnvelopes['coin'] * $bankerUser['odds'];
                $bankerUser_win_coin_total += $banker_win_coin;
                //记录赢到的金币帐变
                $utility->setCoin(
                    array(
                        'uid' => $winer['uid'],
                        'coin' => floatval($banker_win_coin),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 11,
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                    )
                );

                //如果庄家的赔率不是最大倍率，还要将余下的金币退回给参与玩家
                if($maxBetCoin - $banker_win_coin > 0 ){
                    $utility->setCoin(
                        array(
                            'uid' => $v['uid'],
                            'coin' => floatval($maxBetCoin - $banker_win_coin),
                            'gameid' => $game['game']['id'],
                            'liqtype' => 16,
                            'ex1' => $redEnvelopes['id'],
                            'ex2' => $redEnvelopes['issue'],
                        )
                    );
                }

                //赢家统一在后面($bankerUser_win_coin_total)计算抽水
                //$winerprofit_coin = $game['game'][0]['winerprofit']  * $banker_win_coin;
            }else{
                //退回闲家的预投注金额
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => floatval($maxBetCoin),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 9, //赢家，退回对应预投注的红包
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                    )
                );
                //按赔率计算赢到的金额
                $user_win_coin = $redEnvelopes['coin'] * $v['odds'];
                $utility->setCoin(
                    array(
                        'uid' => $v['uid'],
                        'coin' => floatval($user_win_coin),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 11, //赢到的金币
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                    )
                );
                //交门票
                //闲家赢 - 门票
                $ticketcoin = $utility->formatCoin((($user_win_coin + $v['coin']) * $ticket) / 100);
                if($ticketcoin > 0) {
                    $utility->setCoin(
                        array(
                            'uid' => $v['uid'],
                            'coin' => (0 - floatval($ticketcoin)),
                            'gameid' => $game['game']['id'],
                            'liqtype' => 8, //赢到的金币要交门票
                            'ex1' => $redEnvelopes['id'],
                            'ex2' => $redEnvelopes['issue'],
                            'ex3' => ($user_win_coin + $v['coin']) . '×' . $ticket .'%',
                        )
                    );
                }
                $otherUsers[$k]['ticket'] =  $ticketcoin;

                //赢家抽水
                $winerprofit = $utility->formatCoin((($user_win_coin + $v['coin']) * $game['odds'][0]['winerprofit']) / 100);
                if($winerprofit > 0) {
                    $utility->setCoin(
                        array(
                            'uid' => $v['uid'],
                            'coin' => (0 - floatval($winerprofit)),
                            'gameid' => $game['game']['id'],
                            'liqtype' => 10, //赢到的金币要进行抽水
                            'ex1' => $redEnvelopes['id'],
                            'ex2' => $redEnvelopes['issue'],
                            'ex3' => ($user_win_coin + $v['coin']) . '×' . $game['odds'][0]['winerprofit'] .'%',
                        )
                    );
                }
                $otherUsers[$k]['winerprofit'] =  $winerprofit;

                $bankerUser_los_coin_total += $user_win_coin;
            }
        }
        $db->commitTrans();

        //庄家赢利门票及抽水及把余下的预投注还给庄家
        $bankerUser_win_ticket = 0;
        $bankerUser_win_profit = 0;

        $db->beginTrans();
        if($bankerUser_win_coin_total > 0)
        {
            //门票
            $bankerUser_win_ticket = (($bankerUser_win_coin_total + $bankerUser['coin']) *  floatval($game['odds'][0]['ticket'])) / 100;
            if($bankerUser_win_ticket > 0) {
                $bankerUser_win_ticket = $utility->formatCoin($bankerUser_win_ticket);
                $utility->setCoin(
                    array(
                        'uid' => $bankerUser['uid'],
                        'coin' => (0 - floatval($bankerUser_win_ticket)),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 8, //赢到的金币要交门票
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                        'ex3' => ($bankerUser_win_coin_total + $bankerUser['coin']) . '×' . $game['odds'][0]['ticket'] .'%',
                    )
                );
            }
            $bankerUser['ticket'] = $bankerUser_win_ticket;
            //抽水
            $bankerUser_win_profit = (($bankerUser_win_coin_total + $bankerUser['coin']) *  floatval($game['odds'][0]['winerprofit'])) / 100;
            if($bankerUser_win_profit > 0) {
                $bankerUser_win_profit = $utility->formatCoin($bankerUser_win_profit);
                $utility->setCoin(
                    array(
                        'uid' => $bankerUser['uid'],
                        'coin' => (0 - floatval($bankerUser_win_profit)),
                        'gameid' => $game['game']['id'],
                        'liqtype' => 10, //赢到的金币抽水
                        'ex1' => $redEnvelopes['id'],
                        'ex2' => $redEnvelopes['issue'],
                        'ex3' => ($bankerUser_win_coin_total + $bankerUser['coin']) . '×' . $game['odds'][0]['winerprofit'] .'%',
                    )
                );
            }
            $bankerUser['winerprofit'] = $bankerUser_win_profit;
            $bankerUser['ticket'] = $bankerUser_win_ticket;
        }
        //把余款还给庄家
        $back_bankerUser_coin = $bankerUser_maxBetCoin - $bankerUser_los_coin_total;
        if($back_bankerUser_coin > 0){
            $utility->setCoin(
                array(
                    'uid' => $bankerUser['uid'],
                    'coin' => floatval($back_bankerUser_coin),
                    'gameid' => $game['game']['id'],
                    'liqtype' => 16, //庄家还有预投注的余额，退回
                    'ex1' => $redEnvelopes['id'],
                    'ex2' => $redEnvelopes['issue'],
                )
            );
        }
        # 记录庄家赢利红包
        /*
        if($bankerUser_win_coin_total > 0)
        {
            $utility->setCoin(
                array(
                    'uid' => $bankerUser['uid'],
                    'coin' => floatval($bankerUser_win_coin_total),
                    'gameid' => $game['game']['id'],
                    'liqtype' => 11, //庄家还有预投注的余额，退回
                    'ex1' => $redEnvelopes['id'],
                    'ex2' => $redEnvelopes['issue'],
                )
            );
        }
        */
        # 更新betslog的记录
        foreach ($grabUsers as $k=>$v)
        {
            $profit = 0;
            $ticket = 0;
            //如果是庄家
            if($v['uid']==$bankerUser['uid'])
            {
                $idsValue[$k]['value']['ticket'] = $bankerUser_win_ticket;
                $idsValue[$k]['value']['winerprofit'] = $bankerUser_win_profit;
                $grabUsers[$k]['ticket'] = $bankerUser_win_ticket;
                $grabUsers[$k]['winerprofit'] = $bankerUser_win_profit;

                $betNeedCoin = $game['game']['establishcoin'];

                if ($game['game']['ishavebanker']) {
                    //庄家的预计赔注（(人数 -1) * 红包的基本投注 * 最大赔率)）
                    //找出游戏的最大赔率( 游戏的赔率是按从大到小的来排序，所以最上面一个就是最大的赔率，后台设置时需要把牌型最大的winsort值最为最大)
                    $maxodds = $game['odds'][0]['odds'];
                    $betNeedCoin = (($redEnvelopes['need'] - 1) * $redEnvelopes['coin'] * $maxodds);
                }
                $profit = $bankerUser_win_coin_total - $bankerUser_los_coin_total + $v['coin'] - $grabUsers[$k]['ticket'] - $grabUsers[$k]['winerprofit'];

                $grabUsers[$k]['issue_usertype'] = 1;
            }else{
                //其它的就是闲家了
                foreach ($otherUsers as $ok=>$ov)
                {
                    if($v['uid']==$ov['uid'])
                    {
                        $idsValue[$k]['value']['ticket'] = $otherUsers[$ok]['ticket'];
                        $idsValue[$k]['value']['winerprofit'] = $otherUsers[$ok]['winerprofit'];
                        $grabUsers[$k]['ticket'] = $otherUsers[$ok]['ticket'];
                        $grabUsers[$k]['winerprofit'] = $otherUsers[$ok]['winerprofit'];

                        //如果庄家赢
                        if($v['winsort'] < $bankerUser['winsort'])
                        {
                            //按庄家的赔率来计算(最大预投注 - 赔给庄家的金币 - 门票 - 抽水)
                            $profit = $v['coin'] - ($bankerUser['odds'] * $redEnvelopes['coin']) - $otherUsers[$ok]['ticket'] - $otherUsers[$ok]['winerprofit'];
                        }
                        //闲家赢
                        if($v['winsort'] > $bankerUser['winsort']){
                            //按闲家的赔率来计算(最大预投注 - 赔给庄家的金币 - 门票 - 抽水)
                            $profit = ($otherUsers[$ok]['odds'] * $redEnvelopes['coin']) + $otherUsers[$ok]['coin'] - $otherUsers[$ok]['ticket'] - $otherUsers[$ok]['winerprofit'];
                        }
                        //如果winsort相同，对比金额 - 闲家金额大 - 赢
                        if($v['winsort'] == $bankerUser['winsort'] && $v['coin'] > $bankerUser['coin'])
                        {
                            $profit = ($otherUsers[$ok]['odds'] * $redEnvelopes['coin']) + $otherUsers[$ok]['coin'] - $otherUsers[$ok]['ticket'] - $otherUsers[$ok]['winerprofit'];
                        }
                        //如果winsort相同，对比金额 - 闲家金额小 - 输
                        if($v['winsort'] == $bankerUser['winsort'] && $v['coin'] <= $bankerUser['coin'])
                        {
                            $profit = $v['coin'] - ($bankerUser['odds'] * $redEnvelopes['coin']) - $otherUsers[$ok]['ticket'] - $otherUsers[$ok]['winerprofit'];
                        }
                        $grabUsers[$k]['issue_usertype'] = 0;
                    }
                }
            }
            //最终盈利
            $grabUsers[$k]['profit'] = $utility->formatCoin($profit);
            $idsValue[$k]['value']['ticket'] = $grabUsers[$k]['ticket'];
            $idsValue[$k]['value']['profit'] = $grabUsers[$k]['profit'];

            unset($grabUsers[$k]['issue']);
            unset($grabUsers[$k]['gameid']);
            unset($grabUsers[$k]['mantissa']);
            unset($grabUsers[$k]['odds']);
            unset($grabUsers[$k]['userid']);
            unset($grabUsers[$k]['mantissa']);
            //$grabUsers[$k]['times'] = $utility->formatTimes($grabUsers[$k]['times']);
        }
        //更新betslog数据库
        $update_sql = $utility->batchUpdateTable(\Config\Sys::$dbprefix.'betslog', 'id', $idsValue);
        $db->query($update_sql);
        $db->commitTrans();
        #endregion

        $result = array(
            'state' => 200,
            'cmd' => 'gameover',
            'datas' => array(),
            'mantissa' => '',
            'bankercoin' => $betNeedCoin,
            'betcoin' => $redEnvelopes['coin'],
            'ecoin' => $game['game']['establishcoin'], //创建的红包的固定金额（固定费用）
            'ecost' => $game['game']['establishcost'], //参与游戏的费用，固定费用（包底）
            'usedtimes' => $usedtimes, //所花时间
            'needuser' => $redEnvelopes['need'],
            'grabusers' => $grabUsers,
            'times' => $utility->formatTimes($redEnvelopes['begintimes']),
            'issue' => $redEnvelopes['issue'],
            'room_name' => \Config\Sys::$gameprefix . $game['game']['id'],
            'userscoin' => $utility->sendToUidFreeCoinForIssue($grabUsers),
        );
        return $result;
        //Gateway::sendToGroup($redEnvelopes['issue'], json_encode($result));
        //取出列表用户的余额数据并推送
        //$utility->sendToUidFreeCoinForIssue($this->db, $grabUsers);
        //结算数据推送给当期玩家
    }
    # endregion

    # endregion

    public static function divideGameRedPackage($paras){
        global $utility;
        $redcoins = $utility->redPacketRound($paras['c'],$paras['p'],$paras['m']);
        $args = array(
            'uid' => 2,
            'mantissa' => 3,
            'gameid' => 3
        );
        return $utility->getRedPacketFromArray($redcoins,$args);
    }
}